![]()
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 [].