Chapter 10

 

Compiler Error Messages

 

We will come across a large number of errors that state Internal Compiler Error. These errors are extremely dangerous as the compiler itself cannot figure them out. They fall under two broad categories.

 

One, we may have made some dumb mistake which the developers at Microsoft may have not even thought off, thus confusing the compiler thoroughly.

 

Secondly, there could be a genuine bug in the compiler.

 

Take your pick. The first error number CS0001 is an internal compiler error. A catch all phrase for 'I do not know what went wrong'.

 

Thus, the very first compiler error number is thrown when the compiler is totally confused and doesn't know how to react to the error. The compiler will resort to this error as the last error before breaking down. Please understand the irony. The guys who wrote the compiler could have made it the last error number but symbolically made it the first.

 

After studying the different programming languages developed so far over a period, we figured out that the best way to understand more about any programming language is by placing ourselves in the shoes of the sole person who wrote the language.

 

This person did not write the language per se but a compiler through which he expressed his philosophy of the language. Thus, the only way out is to understand the million error messages we receive.

 

This process gets us into the minds of a compiler, thus unearthing what it perceives is right and wrong with our program. Thus, we have endeavored to sprinkle throughout our books every error message the compiler can ever throw at us.

 

After CS0001, we realized that there was no error message CS0002. Since the numerical part of the error number is the only one that changes, we concluded that there can be a maximum of only 9999 errors that we can ever make.

 

In today's world you will rarely come across error number CS0003 as it signifies an out of memory condition. With RAM so cheap today, we will never ever run out of memory. If we do, then the compiler will use our hard disk as memory. This is called virtual memory, and if you come across a CS0003 then consider yourself blessed.

 

a.cs

class zzz

{

public static void Main()

{

int i;

}

}

 

Compiler Warning

a.cs(5,5): warning CS0168: The variable 'i' is declared but never used

 

A variable when not used in the program gives us a benign warning. Some software companies hate compilers producing even a single warning. So, to convert warnings into errors, they implement the /warnaserror option as in

 

>csc /warnaserror a.cs

 

This produces the same warning in the form of an error.

 

Compiler Error

a.cs(5,5): error CS0168: The variable 'i' is declared but never used

 

As an error is reported, the compiler does not generate an exe file.

 

The documentation says that the message number should be CS0004 in the above case. But we fail to understand it as our error number is reported as CS0168.

 

a.cs

class zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

{

}

 

Compiler Error

a.cs(1,7): error CS0645: Identifier too long

 

There are limits to everything in life. In C#, a user defined type cannot exceed 512 characters. These are the limits that the designers imposed on us lowly programmers. Why on earth would anyone create a type or class name larger than 32 characters is beyond our imagination. The above information is useful in game shows to test one's knowledge of unnecessary trivia!

 

a.cs

class zzz

{

public static void Main()

{

string s = -"hell";

}

}

 

Compiler Error

a.cs(5,12): error CS0023: Operator '-' cannot be applied to operand of type 'string'

 

Not all operators can be applied to operands of any data type. So, the unary minus operator cannot be applied to strings. The designers of the string class decided not to have an overload for the minus operator for reasons known only to them. Thus, operator overloading lets you teach an old dog new tricks. You can associate an operator to work with operands of different data types.

 

Compiler Error

error CS0025: Standard library file 'C:\WINDOWS\MICROSOFT.NET\FRAMEWORK\V1.0.2204\mscorlib.dll' could not be found

 

We received the above error when we renamed mscorlib.dll in the above subdirectory to xxx.dll. The compiler, csc, expects certain files in certain directories. If those files are not present we get a CS0025 error. The best alternative here is to reinstall the .NET framework.

 

a.cs

class aaa

{

}

public class zzz

{

public void abc(aaa a)

{

}

public static void Main ()

{

zzz a = new zzz();

a.abc(5);

}

}

 

Compiler Error

a.cs(6,13): error CS0051: Inconsistent accessibility: parameter type 'aaa' is less accessible than method 'zzz.abc(aaa)'

 

Thou shall not spend beyond your means is what has been always taught but we never practiced the adage. Never keep friends that spend more money than you have. Commonsense? In the above example, the class zzz is public and we are calling a function abc in it. This function accepts a parameter that looks like aaa. Unfortunately, as the class aaa has no access modifiers the default is internal. The class zzz as mentioned earlier is public, so it is higher in accessibility than internal. They need to have the same or higher accessibility. The only way out is to remove public from zzz or add a public to class aaa. Also, the class aaa can be public and class zzz may be internal and all yet work fine.

 

So, as we said before, equalize to higher accessibility not lower.

 

a.cs

class aaa

{

}

public class zzz

{

public aaa p1

{

get

{

return new aaa();

}

}

}

 

Compiler Error

a.cs(6,12): error CS0053: Inconsistent accessibility: property type 'aaa' is less accessible than property 'zzz.p1'

 

The same rules apply everywhere. We cannot return an object aaa from a property p1 as it is less accessible than the class zzz.

 

 

a.cs

class aaa

{

}

public class zzz

{

public aaa this[int i]

{

get

{

return new aaa();

}

}

}

 

Compiler Error

a.cs(6,12): error CS0054: Inconsistent accessibility: indexer return type 'aaa' is less accessible than indexer 'zzz.this[int]'

 

Ditto for indexers. They have a separate error message for each concept even though a common one would suffice.

 

a.cs

class aaa

{

}

public class zzz

{

public int this[aaa i]

{

get

{

return 0;

}

}

}

 

Compiler Error

a.cs(6,12): error CS0055: Inconsistent accessibility: parameter type 'aaa' is less accessible than indexer 'zzz.this[aaa]'

 

 

The same rules that hold good for return values also stand true for parameter types as an indexer can have any type as a parameter.

 

To stop further repetition, if an operator returns an aaa in the above case we would get CS0056 and a CS0057 if the parameter is inaccessible. CS0058 deals with delegates and CS0059 for parameters to delegates.

 

a.cs

class aaa

{

}

public class zzz : aaa

{

}

 

Compiler Error

a.cs(4,14): error CS0060: Inconsistent accessibility: base class 'aaa' is less accessible than class 'zzz'

 

We should never ever enter into a marriage with someone far better than us. It simply does not work! In the same way, we cannot derive from a class that is less accessible than we are. In this case, aaa is internal and we are public. Lest you have forgotten, public has no rules associated with it whereas internal applies to the current source file only.

 

a.cs

interface aaa

{

}

public interface zzz : aaa

{

}

 

Compiler Error

a.cs(4,18): error CS0061: Inconsistent accessibility: base interface 'aaa' is less accessible than interface 'zzz'

 

The same rules apply to an interface as to a class. We only have a separate error message.

a.cs

using System;

using System;

 

Compiler Error

a.cs(2,7): warning CS0105: The using directive for 'System' appeared previously in this namespace

 

For various reasons we are not allowed to use the same using directive more than once in our program. There are many things in life that one just does not understand. It does not cause anyone any harm if we include the same using twice. Many people don't do things unless told twice. But, who are we to argue with a compiler?!

 

a.cs

class zzz : yyy

{

new int i;

}

class yyy

{

} 

 

Compiler Warning

a.cs(3,9): warning CS0109: The member 'zzz.i' does not hide an inherited member. The new keyword is not required.

 

The keyword new is used for versioning. It lets you create a new member altogether and has nothing to do with the ones having the same name in the base class. In this case, i is not present in the base class but yet we have used the keyword new with i in zzz. Here the new keyword is redundant but the compiler gives us only a warning and not an error. A warning is something that is not at all serious.

 

a.cs

class zzz : yyy

{

public virtual override void abc()

{

}

}

class yyy

{

public virtual void abc()

{

}

}

 

Compiler Error

a.cs(3,30): error CS0113: A member 'zzz.abc()' marked as override cannot be marked as new or virtual

 

Fire and water do not mix with each other. In the same way there are certain modifiers which cannot be used in conjunction with each other. When we override a function, it replaces a function with the same name in a base class. Also, if we add the new modifier, then we are saying that it overrides the base class function. A contradiction of the first order!

 

A function can only be overridden if it is marked virtual in the base class. No point in saying it again. Override means replace the function in the base class. At the same time if we use the modifier abstract, then we are saying the function has no code. How on earth can we override a function in the base class with one that has no code at all? Two wrongs do not make a right!

 

a.cs

class zzz : yyy {

public override void abc()

{

}

}

class yyy

{

public void abc(int i)

{

}

}

 

 

 

Compiler Error

a.cs(2,22): error CS0115: 'zzz.abc()': no suitable method found to override

 

A function is not known by its name but by its signature. In this case we have two functions carrying the same name but with different signatures. Thus in class zzz there is no suitable function abc in class yyy to override and hence the error. We are asking the compiler to override a function but there is no such function in the base class to override. In the case of new, we only received a slap on our wrists, a warning. Here we get an error instead.

 

a.cs

public class zzz {

static zzz(int o)

{

}

}

 

Compiler Error

a.cs(2,8): error CS0132: 'zzz.zzz(int)': a static constructor must be parameterless

 

Static constructors are a new concept in programming languages. They are called at the time of loading the class and hence we can never call them, only the system calls them. The system never calls them with parameters and hence the above error indicates that a static constructor cannot accept parameters.

 

a.cs

class zzz

{

public static int i = 2;

public static void Main()

{

{

int i = 6;

}

i++;

}

}

Compiler Error

a.cs(9,1): error CS0135: 'i' conflicts with the declaration 'zzz.i'

 

The problem here is a logical one and not one of syntax. The variable i created in function Main dies at the end of the brace. Then the static i created outside Main is incremented. What the compiler is upset about is the fact that in the Main function it encounters two variables with the same name i. Being uncomfortable with this situation, it drops an error.

 

The meaning of a variable must not be changed within a function, thus name hiding generates the above error.

 

a.cs

class yyy

{

}

class zzz

{

public static void Main()

{

try {}

catch ( yyy a) {}

}

}

 

Compiler Error

a.cs(9,9): error CS0155: The type caught or thrown must be derived from System.Exception

 

The catch clause takes a parameter which is either an instance of a class System.Exception or a class derived from System.Exception. Here yyy is not derived from System.Exception and hence the error.

 

a.cs

class zzz {

int i;

public int j;

public static void Main() {

}

}

Compiler Error

a.cs(2,5): warning CS0169: The private field 'zzz.i' is never used

a.cs(3,12): warning CS0649: Field 'zzz.j' is never assigned to, and will always have its default value 0

 

a private member and a public member when not used gives two different warnings. The second warning very clearly informs us that the public variable has been initialized to zero, which does not happen in the case of private variables.

 

a.cs

class zzz

{

int i;

public int j;

public static void Main()

{

zzz a = new zzz();

System.Console.WriteLine(a.i+" " + a.j);

}

}

 

Compiler Warning

a.cs(3,5): warning CS0649: Field 'zzz.i' is never assigned to, and will always have its default value 0

a.cs(4,12): warning CS0649: Field 'zzz.j' is never assigned to, and will always have its default value 0

 

Output

0 0

 

However, if we create an object that looks like zzz, then the compiler does not distinguish between public and private and gives the same warning. Contrast it with the situation earlier. You can figure out these different warnings yourselves.

 

a.cs

struct yyy

{

public int i;

}

class zzz

{

public static void Main()

{

yyy a;

System.Console.WriteLine(a.i);

}

}

 

Compiler Error

a.cs(10,26): error CS0170: Use of possibly unassigned field 'i'

 

The designers of the C# language investigated as to why programs fail very often. They came about with the conclusion that programmers hate initializing variables. These variables, thus, have a random value when they are being used. To eliminate such errors, the designers forbade us from using a variable without giving it an initial value. A structure is also a collection of variables and what applies to one variable also applies to a collection. Thus, the compiler makes sure that each and every variable is given a value before we can use them.

 

a.cs

class zzz

{

public static void Main()

{

base = 10;

System.Console.WriteLine(base);

}

}

 

Compiler Error

a.cs(5,1): error CS0175: Use of keyword base is not valid in this context

a.cs(6,26): error CS0175: Use of keyword base is not valid in this context

 

Like it or not, all objects are derived from a base class called Object. If we happen to be in a derived class and we want to access a base class member irrespective of whether it is hidden or not, the base keyword is to be used. This keyword is to be used to access base class members only.

 

a.cs

class zzz

{

public void abc(out int i)

{

}

}

 

Compiler Error

a.cs(3,13): error CS0177: The out parameter 'i' must be assigned to before control leaves the current method

 

An out parameter must be initialized before the function ends. This is because an out parameter does not have to be initialized at the time of calling the function. The compiler guarantees this and ensures that the out variable has been given a value. The reverse applies to ref also. We have to give ref parameters a value before calling a function.

 

a.cs

class zzz

{

public extern void abc()

{

}

}

 

Compiler Error

a.cs(3,20): error CS0179: 'zzz.abc()' cannot be extern and declare a body

 

Whenever we specify a function as extern, it is our way of telling the compiler that the code of the function is located in a different file. Hence, we should not be allowed to add code to our function. If we do break this rule, we will get the above error. Extern functions cannot have a definition.

 

 

a.cs

class zzz

{

public abstract extern void abc();

}

 

Compiler Error

a.cs(3,29): error CS0180: 'zzz.abc()' cannot be both extern and abstract

 

The modifiers extern and abstract both finally mean the same. No code allowed for the function. In the case of abstract, the code will be supplied by the derived class and in extern from some other place, maybe outside the current file. Thus abstract and extern are mutually exclusive.

 

a.cs

public class zzz

{

static string s;

[System.Diagnostics.ConditionalAttribute(s)]

static void Main()

{

}

}

 

Compiler Error

a.cs(4,42): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression

 

The parameters passed to an attribute can be one of the types as mentioned in the above error. Thus we cannot use a variable as a parameter in the above case even though we are giving it a string data type, which the parameter to the attribute expects it to be.

 

a.cs

class zzz

{

public static void Main()

{

if (((System.Object) null) is string)

;

}

}

 

Compiler Error

a.cs(5,7): error CS0186: Use of null is not valid in this context

 

A null represents no object at all. Thus we are not allowed to cast null into any other data type.

 

a.cs

struct yyy

{

int j;

yyy(int i)

{

abc();

j = i;

}

void abc()

{

}

}

 

Compiler Error

a.cs(6,1): error CS0188: The this object cannot be used before all of its fields are assigned to

 

In a structure, we must first initialize all the members of the structure before calling a function within it. Remember all references are prefaced by a this. Calling the function abc in yyy is equivalent to this.abc().

 

a.cs

struct yyy

{

yyy(int i)

{

abc();

}

void abc()

{

}

}

 

Compiler Error

a.cs(5,1): error CS0188: The this object cannot be used before all of its fields are assigned to

 

So pigheaded is the compiler that even though we have no variables in the structure it yet gives us an error. The compiler does not realize that we have no variables at all in the structure. Maybe the next version of the compiler will not give us such an error.

 

The only explanation we can provide is that if we have a constructor with parameters, then we have to initialize at least one variable. This also means we need at least one variable in the structure.

 

a.cs

class zzz

{

public readonly int i = 10;

zzz()

{

i = 3;

}

public static void Main()

{

zzz a = new zzz();

a.i = 4;

}

}

 

Compiler Error

a.cs(11,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)

 

A readonly variable can only be initialized in a constructor or at the time of creation. Anywhere else is a no-no as it would defeat the very concept of being readonly.

 

a.cs

class zzz

{

public static readonly int i = 10;

zzz()

{

i = 3;

}

public static void Main()

{

}

}

 

The error reported is the same as before as the readonly variable i is static and the constructor in which it is being initialized is not static. Add the static modifier to the constructor and watch the error fly away.

 

a.cs

class zzz

{

public static readonly int i = 10;

public static void abc( ref int j)

{

}

public static void Main()

{

zzz.abc(ref i);

}

}

 

Compiler Error

a.cs(9,13): error CS0199: A static readonly field cannot be passed ref or out (except in a static constructor)

 

A static readonly field cannot be passed as a parameter to a function like a normal readonly variable.

 

A statement comprises five entities: an assignment, increment, decrement, call and a new.

 

a.cs

public class zzz

{

public void GetEnumerator ()

{

}

public static void Main ()

{

zzz z = new zzz();

foreach (zzz x in z)

{

}

}

}

 

Compiler Error

a.cs(9,1): error CS0202: The call to GetEnumerator must return a class or a struct, not 'void'

 

The GetEnumerator function must return a class or a struct, surely not a void.

 

One error that we did not have the heart to shown you is CS0204. This one pops up when you have more than 65535 local variables in your program. Who on earth has the time to create so many variables and we doubt whether anyone on earth has ever seen this error message? Trust is what makes the world go round and we trust the documentation.

 

a.cs

public class zzz

{

public static void abc(params int[] a, __arglist)

{

}

}

 

Compiler Error

a.cs(3,24): error CS0231: A params or __arglist parameter must be the last parameter in a formal parameter list

 

We cannot use the __arglist and params together as parameters to a function. Either one of it is used. This is because both of them are an array and they mop up whatever is left over of the parameters. The __arglist is used to access parameters passed to a function.

 

a.cs

public class zzz

{

public static void Main()

{

int i;

System.Console.WriteLine(sizeof(i));

}

}

 

Compiler Error

a.cs(6,26): error CS0233: sizeof can only be used in an unsafe context (consider using System.Runtime.InteropServices.Marshal.SizeOf)

 

The sizeof is a remnant of the C programming language. Hence we can only use it in an unsafe context. In our opinion, these are unnecessary restrictions placed on us by the compiler. Who listens to the underdog?

 

a.cs

public class zzz

{

public static void Main()

{

int i = 10;

System.Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(i));

}

}

 

Output

4

 

We took the advise of the error message and used the SizeOf function in the class Marshal.  We did receive the same answer that sizeof would have given us in unsafe conditions.

The only hitch here is that i must be initialized in advance. Such is not the case with the sizeof keyword. This is one of the major difference between a function and a keyword. Something that the language understands is treated differently from a parameter to a function.

 

a.cs

abstract class zzz

{

public abstract void abc()

{

}

}

 

Compiler Error

a.cs(3,22): error CS0500: 'zzz.abc()' cannot declare a body because it is marked abstract

 

The concept of abstract expects the derived class to write the code for the abstract functions. Thus, we cannot write the code ourselves by specifying a body.

 

a.cs

abstract class zzz

{

public virtual abstract void abc();

}

 

Compiler Error

a.cs(3,30): error CS0503: The abstract method 'zzz.abc()' cannot be marked virtual

 

The compiler hates repetition. An abstract function is by default virtual and it gets upset if you specify virtual again. Maybe the next version should be a lot more considerate when we state the obvious again. Honestly, this would slim down the number of error messages.

 

a.cs

class zzz : yyy {

public override void abc()

{

}

}

class yyy

{

public int abc;

}

 

Compiler Error

a.cs(2,22): error CS0505: 'zzz.abc()' : cannot override; 'yyy.abc' is not a function

 

We can only override a function provided a function with the same name is present in the base class. Here abc is an int in the base class, not a function name and hence the error.

 

a.cs

class zzz : yyy

{

static zzz() : base()

{

}

}

class yyy

{

}

 

Compiler Error

a.cs(3,8): error CS0514: 'zzz.zzz()': static constructor cannot have an explicit this or base constructor call

 

A static constructor is not allowed to call the static constructor of the base class using the keyword base. The problem with static is that anything to do with it has to be known at compile time only whereas the keyword this has a value only at run time. Plus, static functions are not passed this and base as parameters.

 

a.cs

class zzz

{

public static zzz()

{

}

}

 

Compiler Error

a.cs(3,15): error CS0515: 'zzz.zzz()': access modifiers are not allowed on static constructors

 

A static constructor is called when the object is loaded. Thus, as it is an internal thing, we are not allowed to use any access modifiers on static constructors.

 

a.cs

class zzz

{

public zzz() : this()

{

}

}

 

Compiler Error

a.cs(3,8): error CS0516: Constructor 'zzz.zzz()' cannot call itself

 

A constructor can use the keyword this and base to call any other constructor but itself.

 

a.cs

class zzz {

public zzz() : this(10)

{

System.Console.WriteLine("Void");

}

public zzz(int i) : this()

{

System.Console.WriteLine("One");

}

public static void Main()

{

System.Console.WriteLine("Start");

zzz a = new zzz();

}

}

Output

Start

 

In our belief, the compiler does not try hard enough to detect circular references. Here the constructors are blindly calling each other and the compiler is blind to their doings. Thus, it is easy to go into an indefinite loop while writing code. At times, we may receive a runtime error stating: Unhandled Exception: StackOverflowException.

 

a.cs

struct zzz

{

public zzz(int i) : base(i)

{

}

}

 

Compiler Error

a.cs(3,8): error CS0522: 'zzz.zzz(int)': structs cannot call base class constructors

 

Structures cannot call the base class constructors as they in their very nature are sealed. Hence, what the structure derives from cannot be called also. The other reason could be that they are created on the stack. Thus, structures and classes in a sense are a lot similar but a lot dissimilar too.

 

a.cs

struct zzz

{

yyy a;

}

struct yyy

{

zzz b;

}

 

Compiler Error

a.cs(7,5): error CS0523: Struct member 'yyy.b' of type 'zzz' causes a cycle in the structure layout

You rely on someone to do a job and he relies on you to do the same job. Chaos is the result. Hence, in the struct zzz we have a member a that is an instance of a type yyy and struct yyy in turn has a member called b that is an instance of zzz. This causes a cycle. The complier thus throws its hands up in the air and gives up. Cyclic references are like plague

 

a.cs

interface iii

{

public class zzz

{

}

}

 

Compiler Error

a.cs(3,14): error CS0524: 'zzz': interfaces cannot declare types

 

You can do lots of things in an interface but you cannot create your own class within them.  A nested class is not permissible in an interface. The reason for the restriction is that classes carry code with them and an interface cannot have any code in it.

 

a.cs

interface iii

{

int i;

}

 

Compiler Error

a.cs(3,1): error CS0525: Interfaces cannot contain fields

 

Interfaces are all fluff. They cannot have anything concrete. They are only rules that others have to obey. Thus, a field, which is something finished, something complete cannot reside in an interface.

 

a.cs

interface iii {

iii();

}

Compiler Error

a.cs(2,1): error CS0526: Interfaces cannot contain constructors

 

Interfaces cannot have a whiff of code. So having constructors is out of question. It cannot also have the definition or a prototype of a constructor as it will then have to be filled with code. Thus, constructors are not allowed to have a constructor definition.

 

a.cs

interface iii

{

}

class zzz : iii,iii

{

}

 

Compiler Error

a.cs(4,17): error CS0528: 'iii' is already listed in interface list

 

The compiler would hate seeing a movie with a double role. You cannot derive from a interface twice. A class can derive from multiple interface but not from the same one twice. Makes sense. Why would anyone do something so foolhardy?

 

a.cs

interface iii : jjj {

}

interface jjj : iii

{

}

 

Compiler Error

a.cs(1,11): error CS0529: Inherited interface 'jjj' causes a cycle in the interface hierarchy of 'iii'

 

Anything cyclic is a problem for the compiler. Here we will go on and on in a indefinite loop as interface iii depends upon interface jjj which again depends upon iii.

 

a.cs

abstract public class zzz 

{

abstract public void abc();

}

abstract public class yyy : zzz

{

new abstract public void abc();

}

 

Compiler Error

a.cs(7,26): error CS0533: 'yyy.abc()' hides inherited abstract member 'zzz.abc()'

 

Class yyy is derived from zzz and they both have an abstract function called abc. In the class yyy abc has a new modifier, thus it has nothing to do with the base class abc. The problem is that the base class abc has no code at all and thus making the yyy class abc new makes no sense. New assumes that we are creating a different function over the base class.

 

a.cs

public class zzz : yyy

{

public static void abc()

{

}

}

interface yyy

{

void abc();

}

 

Compiler Error

a.cs(1,14): error CS0536: 'zzz' does not implement interface member 'yyy.abc()'. 'zzz.abc()' is either static, not public, or has the wrong return type.

 

Any mistake on our part gives an error. Interface yyy contains a function abc which is to be implemented in zzz. But while implementing it in zzz,  we made it static. The compiler is very clear on one point. Implement the entire function including return type and access modifiers as they are in the interface otherwise conk out. No deviations from the original is allowed under any circumstances.

 

a.cs

class zzz : yyy

{

void yyy.abc()

{

}

}

class yyy

{

}

 

Compiler Error

a.cs(3,6): error CS0538: 'yyy' in explicit interface declaration is not an interface

 

We are allowed to specify the interface name before a function with a dot as a separator. This is because we are allowed to implement a class from multiple interfaces, which may carry the same function name. However, yyy is the name of a class and not a interface.

 

a.cs

interface zzz : yyy

{

void yyy.abc();

}

interface yyy

{

void abc();

}

 

Compiler Error

a.cs(3,6): error CS0541: 'yyy.abc': explicit interface declaration can only be declared in a class or struct

 

We are only allowed to use the explicit interface notation in a class or a structure. Within another interface, it is not accepted. This speaks of sound common sense as an interface can never ever carry code and thus cannot carry the definition or code of the function either. Thus specifying the interface the function dwelled in does not make any sense.

 

a.cs

class zzz : yyy

{

public override int i

{

set {}

}

}

class yyy

{

public int i;

}

 

Compiler Error

a.cs(3,21): error CS0544: 'zzz.i' : cannot override; 'yyy.i' is not a property

 

We can have a property called i in the derived class and a variable called i in the base class. The compiler can live with it and they can both coexist. The problem starts the moment we override the property i in the derived class. This is not allowed as we have no property by the same name in the base class. We have only a lowly variable.

 

a.cs

class zzz : yyy

{

public override int i

{

set {}

get { return 0;}

}

}

class yyy {

virtual public int i

{

set { }

}

}

Compiler Error

a.cs(6,1): error CS0545: 'zzz.i.get': cannot override because 'yyy.i' does not have an overridable get accessor

 

A property does not exist by itself. It comes along with a get and set accessor. You cannot exceed what the designers chose to implement in the base class. Only things that are virtual in the base class can be overridden. So, the only way out of the above quandary is to define a  get like the set.

 

a.cs

sealed class zzz

{

public virtual void abc()

{

}

}

 

Compiler Error

a.cs(3,21): error CS0549: 'zzz.abc()' is a new virtual member in a sealed class 'zzz'

 

The sole purpose of virtual in life is to ensure overriding of a function in he base class within the derived class. A sealed class cannot be used as a base class and hence virtual functions are a contradiction in terms.

 

a.cs

class zzz : iii

{

int iii.i

{

set {}

}

}

interface iii

{

int i

{

get;

}

}

Compiler Error

a.cs(3,5): error CS0551: Explicit interface implementation 'zzz.iii.i' is missing accessor 'iii.i.get'

a.cs(5,1): error CS0550: 'zzz.iii.i.set' adds an accessor not found in interface member 'iii.i'

a.cs(1,7): error CS0535: 'zzz' does not implement interface member 'iii.i.get'

 

In an interface we have a property i with a get and no set. In the derived class, we have not added the same property but instead given a set property. The compiler throws error messages as it feels we are confused with what we were trying to achieve.

 

a.cs

public class zzz

{

public ~yyy()

{

}

}

 

Compiler Error

a.cs(3,9): error CS0574: Name of destructor must match name of class

 

A destructor is called a destructor because it is of the same name as the name of the class. You cannot have any other name starting with a ~ in a class.

 

a.cs

interface iii

{

void abc();

}

public class zzz : iii

{

[System.Diagnostics.ConditionalAttribute("hi")]

void iii.abc()

{

}

}

 

Compiler Error

a.cs(7,2): error CS0577: Conditional not valid on 'zzz.iii.abc()' because it is a constructor, destructor, operator, or explicit interface implementation

 

An attribute cannot be used anywhere and everywhere. Fools rush in where angels fear to tread. Thus, we cannot use the ConditionalAttribute on a constructor, destructor, operator, or explicit interface implementation. The error message informs us the same.

 

a.cs

public class zzz

{

[System.Diagnostics.ConditionalAttribute("hi")]

int abc() {

}

}

 

Compiler Error

a.cs(3,2): error CS0578: Conditional not valid on 'zzz.abc()' because its return type is not void

 

When creating an attribute you can be extremely picky about where it can be used. The ConditionalAttribute can be used only above functions that return void. One more rule to remember!

 

a.cs

using System.Runtime.CompilerServices;

public class zzz

{

[IndexerName("abc", "def")]

public int this [int index]

{

set {}

}

}

 

Compiler Error

a.cs(3,14): error CS0580: Too many unnamed arguments to attribute 'IndexerName'

Attributes have their own set of rules and regulations. The designers of the IndexerName attribute allowed only a single parameter of a string data type. We are passing it two strings and hence the error.

 

a.cs

using System.Runtime.CompilerServices;

public class zzz

{

[IndexerName("abc", vijay=2)]

public int this [int index]

{

set {}

}

}

 

Compiler Error

a.cs(3,2): error CS0581: Named arguments not allowed on attribute 'IndexerName'

 

We are also not allowed to use named arguments, as the attribute does not understand them.

 

a.cs

interface iii

{

[System.Diagnostics.ConditionalAttribute("DEBUG")] 

void zz();

}

 

Compiler Error

a.cs(3,2): error CS0582: Conditional not valid on interface members

 

We are not allowed to use the ConditionalAttribute on an interface member. We can decide with the precision of a stealth bomber where an attribute is allowed. This is one more restriction on an interface member.

 

a.cs

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential | LayoutKind.Explicit)]

class zzz

{

}

 

An attribute cannot have options, which are contradictory in the definition of the attribute. In the above case, both of them are valid.

 

a.cs

class zzz

{

void this [int i]

{

set {}

}

}

 

Compiler Error

a.cs(3,6): error CS0620: Indexers cannot have void type

 

Indexers, Properties, Operators cannot have void return types as they are diligent in the job they perform and always return values.

 

a.cs

class zzz

{

virtual void abc()

{

}

}

 

Compiler Error

a.cs(3,14): error CS0621: 'zzz.abc()' : virtual or abstract members cannot be private

 

By default, a member in a class is marked private. This prohibits the derived classes from accessing its private functions.

 

A virtual function allows derived classes to override its function whereas an abstract function is implemented in a derived class. Hey, wait a minute! A private function cannot be accessed in a derived class as we mentioned a couple of lines earlier. Thus, a private function cannot be tagged with the modifiers virtual and abstract.

 

a.cs

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)]

struct zzz

{

[FieldOffset(5)]

public int i;

public int j;

}

 

Compiler Error

a.cs(7,12): error CS0625: 'zzz.j' : Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.

 

The StructLayout attribute lets you decide on the memory layout for the structure. Normally the compiler decides where in memory the individual fields will start but at certain times, we would like to decide where in memory the fields should begin.

 

The parameter to the attribute, which will give us complete freedom in laying out the fields in memory is called LayoutKind.Explicit. This freedom comes at a price. We have to individually specify where each field starts using the FieldOffset Attribute. This is no partnership where we supply some and the compiler does the rest. The destiny of the structure is now in our hands. We cannot miss out any field as we did in the above example with variable j.

 

a.cs

sealed class zzz

{

protected void abc()

{

}

public static void Main()

{

}

}

Compiler Error

a.cs(3,16): warning CS0628: 'zzz.abc()' : new protected member declared in sealed class

 

Remember warnings are not life-threatening at all. A protected member only allows a derived class to use a function and a sealed class cannot be derived from, hence the compiler thinks we are confused or lost. May be it thinks we should have used private instead as in this case the protected gets downgraded to private access. No big deal and thus a warning.

 

a.cs

class zzz : iii

{

[System.Diagnostics.Conditional("debug")]

public void abc()

{

}

}

interface iii

{

void abc();

}

 

Compiler Error

a.cs(4,13): error CS0629: Conditional member 'zzz.abc()' cannot implement interface member 'iii.abc()'

 

This particular attribute cannot be used on an interface function. Ask the guys who designed the attribute what was on his mind when he placed the above restriction.

 

a.cs

class zzz

{

public int this[ref int i]

{

}

}

 

 

Compiler Error

a.cs(3,12): error CS0631: Indexers can't have ref or out parameters

 

It does not make any sense for an indexer to have parameters that can be ref or out and as the parameter to an indexer is nothing but an index of an array. Normally the parameter to an indexer would be a number only which cannot be changed. Also, if we used a variable, changing its value in an indexer would lead to confusion all around.

 

a.cs

[zzz]

class zzz {

}

 

Compiler Error

a.cs(1,2): error CS0616: 'zzz': is not an attribute class

 

An attribute must be a class derived from System.Attribute. This condition must be adhered to at all costs. This is because the system can call lots of functions from the System.Atribute class and we can override the functions if we want to change the behavior of the attribute.

 

a.cs

[xxx]

public class zzz {

[yyy]

int i;

}

abstract class yyy : System.Attribute

{

}

class xxx : yyy

{

}

 

Compiler Error

a.cs(4,2): error CS0653: Cannot apply attribute class 'yyy' because it is abstract

An abstract class cannot get a job anywhere as it cannot be used anywhere. Such a class is incomplete and unless completed it cannot be of any help to society. Thus, the class yyy, an abstract class, cannot participate as an attribute but class xxx can as it is not abstract. xxx must implements all the abstract functions of class yyy.

 

a.cs

public class zzz

{

public static void Main()

{

int i = abc;

}

public static int abc()

{

return 1;

}

}

 

Compiler Error

a.cs(5,9): error CS0654: Method 'zzz.abc()' referenced without parentheses

 

Function names have no great significance in the C# programming language. We only use them to execute a function after specifying the name and () brackets with parameters within them.

 

a.cs

public class zzz {

public static public void Main()

{

}

}

 

Compiler Error

a.cs(3,15): error CS1004: Duplicate 'public' modifier

 

Two of the same is what the compiler hates. Here we are not allowed to specify the same modifier twice. Hey we meant no harm but who is listening. They do not have to be physically together on the line for the error to be flagged.

 

a.cs

public class zzz {

public static void Main()

{

object *p;

}

}

 

Compiler Error

a.cs(5,8): error CS1005: Indirection to managed type is not valid

 

A * signifies a pointer and the managed types like object etc cannot be accessed through a pointer. Pointers were created for being used by the value types.

 

a.cs

public class zzz

{

public int i

{

set {}

set {}

}

}

 

Compiler Error

a.cs(6,5): error CS1007: Property accessor already defined

 

You cannot say or do the same thing twice. As we are creating the same set accessor twice, which one should the compiler take heed off. It chooses neither and gives you a simple error.

 

a.cs

public class zzz {

int i

{

aa {}

}

}

Compiler Error

a.cs(4,1): error CS1014: A get or set accessor expected

 

A property can only contain a get and a set.. We cannot place any arbitrary function name within a property.

 

a.cs

public class zzz

{

public zzz () :  

{

}

}

 

Compiler Error

a.cs(4,1): error CS1018: Keyword this or base expected

 

After the name of the constructor, we have complete control over which constructors to call though it is optional. If we specify a :, then we have to use base or this to call the appropriate constructor. If we leave it blank, all hell breaks loose and we get an error.

 

a.cs

class zzz

{

}

}

 

Compiler Error

a.cs(4,1): error CS1022: Type or namespace definition, or end-of-file expected

 

An extra brace } added by mistake does not result in a simple English like error. Instead, we get end of file expected. Where is the neighbourhood going these days?

 

a.cs

#vijay

 

Compiler Error

a.cs(1,2): error CS1024: Preprocessor directive expected

Anything after the # or pound sign can only be the name of a preprocessor symbol and not anything else. As there are very few preprocessor symbols, we do not have much of a choice here.

 

a.cs

#if true /*

 

*/

#endif

 

Compiler Error

a.cs(1,10): error CS1025: Single-line comment or end-of-line expected

 

After a preprocessor directive, we can only use the single line comments and not the multiple line comments.

 

a.cs

#if true 2

#endif

 

Compiler Error

a.cs(1,10): error CS1025: Single-line comment or end-of-line expected

 

Any other preprocessor error also results in a CS1025. May be as the preprocessor has lost its importance in C# compared to C, they did not have separate error messages for the preprocessor and used CS1025 as a catch all for all errors.

 

a.cs

#if ( a== b

#endif

 

Compiler Error

a.cs(1,13): error CS1026: ) expected

 

However, some common errors like closing a ) bracket are caught by the compiler.

 

 

a.cs

#endif

 

Compiler Error

a.cs(2,2): error CS1028: Unexpected preprocessor directive

 

When you catch the compiler with its pants down it gives you error CS1028. Here the compiler saw an #endif with no matching #if. Instead of sending us to the loony bin, it gave us the above error. Hey, relax, mistakes always happen!

 

a.cs

/*

 

Compiler Error

a.cs(1,1): error CS1035: End-of-file found, '*/' expected

 

All good things in life must come to an end even though we do not want them to. In this case, we have a start of a multi-line comment but no end of multi line comment in sight.

 

a.cs

public class zzz

{

public static void Main()

{

string b = @"hell;

}

}

 

Compiler Error

a.cs(5,12): error CS1039: Unterminated string literal

 

All strings have to end with " as they start off with a ". If the @ sign is not around, you will receive another error. Like in life end what you start.

 

a.cs

/* */ #define aa

 

 

Compiler Error

a.cs(1,7): error CS1040: Preprocessor directives must appear as first non-whitespace character on a line

 

We all like coming first in life and it is the same with a preprocessor directive. We cannot place it anywhere else,  it has to be the first character of a line. The number of spaces or white spaces are counted as valid characters and like life ignores you and me, spaces are ignored by the compiler.

 

a.cs

public class zzz

{

public st\u0061tic void Main()

{

}

}

 

Compiler Error

a.cs(3,20): error CS1519: Invalid token 'void' in class, struct, or interface

 

A Unicode character set begins with a \u and a number, which the Unicode character is known by. A small a is known by the number 97 or 61 in hex. We are not allowed to use the Unicode characters in keywords. Maybe it brings in more work for the compiler.

 

a.cs

public class zzz

{

public static void Main()

{

abc(ref 10);

}

public static void abc(ref int i)

{

}

}

 

Compiler Error

a.cs(5,9): error CS1510: A ref or out argument must be an lvalue

A ref or an out must be a lvalue. An lvalue is nothing but a variable that represents some memory. A property is not an lvalue as it is a function and does not stand for a memory location. A ref and out parameter require a memory location.

 

a.cs

class zzz  : yyy

 {  

public static void Main ()

{

base.j = 3;

}

}

class yyy

{

public static int j;

}  

 

Compiler Error

a.cs(5,1): error CS1511: Keyword base is not available in a static method

 

Static is like the odd kid on the block. It cannot perform a lot more than a non-static member. It has, for example, no access to the keyword base with which it can access members of the base class. The reason being that static means one and only one and this and base are used to access multiple instance values.

 

a.cs

class zzz  : yyy

{  

int k = base.j;

}

class yyy

{

public static int j=10;

}  

 

Compiler Error

a.cs(3,9): error CS1512: Keyword base is not available in the current context

We are not allowed to use the keyword base outside of a function, property or a constructor. You can consider it as an extra parameter to a function. It represents the class we are derived from.

 

a.cs

class zzz 

  

Compiler Error

a.cs(3,4): error CS1514: { expected

 

Whenever we use keywords like class, namespace, the compiler checks for an open the brace.  If this character is omitted, then it stops in its tracks and immediately before you can say 'halleluiah' it will throw up an error!

 

a.cs

class zzz 

{

abc()

{

}

}  

  

Compiler Error

a.cs(3,1): error CS1520: Class, struct, or interface method must have a return type

 

A method can be placed in any of the following three places, a class, struct or an interface. There are no assumptions made by the compiler. All functions have to return a value and even if they do not, we have to explicitly specify that they do not. In the above case, the function abc does not return any value and the compiler does not guess or assume a return value for it.

 

a.cs

class zzz  : yyy[]

{

}  

class yyy

{

}  

Compiler Error

a.cs(1,18): error CS1521: Invalid base type

 

Whenever we use an invalid character in the name of the base class, we are confronted with the above error. If we use the wrong name of a class, we are given a CS0234 error. Thus, only an ill-formed base class name causes the above error.

 

a.cs

class zzz

{

public static void Main()

{

void i;

}

}

 

Compiler Error

a.cs(5,1): error CS1547: Keyword 'void' cannot be used in this context

 

A void data type can only be used with a function. It denotes absence of a return value. A variable cannot represent absence or no value. Thus, no data type can represent a void or no value. For these reasons, the compiler has reserved one error message explicitly for it.

 

a.cs

class zzz

{

public static void Main()

{

5 + [ + throw + void;    

}

}

 

Compiler Error

a.cs(5,5): error CS1525: Invalid expression term '['

a.cs(5,9): error CS1525: Invalid expression term 'throw'

a.cs(5,17): error CS1525: Invalid expression term 'void'

 

You are not allowed to write whatever you want and wherever you want especially in an expression. We are not allowed to use reserved words indiscriminately anywhere we like. Thus, words like void are a no-no in expressions. The compiler reserves error number CS1457 for your sloppiness.

 

a.cs

class zzz

{

public static void Main()

{

zzz a = new zzz;

}

}

 

Compiler Error

a.cs(5,16): error CS1526: A new expression requires () or [] after type

 

The compiler is extremely unforgiving. If we forget even the () after new, it screams its head off at us. Whenever we call new, we are executing a constructor, which may or may not be passed parameters. That is the rationale behind the () brackets after new. Even though we have no parameters to be passed to the constructor, we have to use the new syntax. Ditto for [].