You are on page 1of 41

Concepts Revisited - C# Nuts and Bolt - Beta2

Chapter 1

Concepts Revisited
Entry Point
The first function to be called in any C# program is Main. Obviously someone at Microsoft tossed a coin and as it fell 'heads', they chose Main. Had it been 'tails', one wonders what the first function would have been called. As everything starts from Main, it is also called the entry point of the program. It is the fountainhead of all knowledge. Incidentally, the C programming language also calls Main as its first function for all C-language programs. We can have as many as four different ways to declare Main in our program. They are as follows:
static static static static void Main() {...} int Main() {...} void Main(string[] a) {...} int Main(string[] args) {...}

The operating system calls Main and waits for it to return a value. This value denotes the success or failure of the program. Main can either return a number or result in no return value, that is, void. If it returns an int, by convention, a value of zero means success and any other value indicates an error. No international authority can standardize the error numbers, it largely depends on the programmer himself. Copy as a command takes two parameters; the source and destination files. Similarly, a C# program can also accept command line parameters at runtime. The executable a.exe can be entered as
>a one two three a.cs class zzz { public static void Main(string[] a) { int i; for ( i=0; i< a.Length; i++) System.Console.WriteLine(a[i]); } (1 of 41)2/21/2010 7:37:57 PM

Concepts Revisited - C# Nuts and Bolt - Beta2

} Output one two three

one, two, three are called command line parameters. The program accepts them in an array of strings. As the array is a parameter to the function, we are free to decide on its name. Every array has a member called Length, which tells us the size of the array. In our case, it is three. Thus, a[0] will contain the first word one and not the name of the program, a[1] will contain two and a[3] - three. Main now behaves like any other function. What we do next with the command line arguments depends entirely upon us.
a.cs class zzz { public static void Main(string[] a) { } public static int Main() { } } Compiler Error a.cs(3,20): error CS0017: Program 'a.exe' has more than one entry point defined: 'zzz.Main(string[])' a.cs(6,19): error CS0017: Program 'a.exe' has more than one entry point defined: 'zzz.Main()'

You can have one and only one function called Main in any C# program. Even though you can call it with different parameters, with the name changing, Main as a function must be given only once.
a.cs class zzz { public static void Main(int i) { } } Compiler Warning a.cs(3,21): warning CS0028: 'zzz.Main(int)' has the wrong signature to be an entry point Compiler Error error CS5001: Program 'a.exe' does not have an entry point defined

Here, the compiler first displays a warning signaling us that Main has not been created with the right parameters. The error, following the warning, proclaims that we have forgotten to create a function called Main. The signature includes the return type only in special cases as entry point. (2 of 41)2/21/2010 7:37:57 PM

Concepts Revisited - C# Nuts and Bolt - Beta2

a.cs class zzz { public static long Main() { return 0; } } Compiler Warning a.cs(3,20): warning CS0028: 'zzz.Main()' has the wrong signature to be an entry point Compiler Error error CS5001: Program 'a.exe' does not have an entry point defined

The signature refers to the parameters given to the function plus the return value. Main in the above program returns 'long', hence we see the error.
a.cs class zzz { public void Main() { } } Compiler Error error CS5001: Program 'a.exe' does not have an entry point defined

The signature also includes modifiers like static etc. It just proves the importance of the function Main and the way it has been defined.
a.cs class zzz { public static void Main() { } } class yyy { public static void Main() { } } Compiler Error a.cs(2,21): error CS0017: Program 'a.exe' has more than one entry point defined: 'zzz.Main()' a.cs(8,21): error CS0017: Program 'a.exe' has more than one entry point defined: 'yyy.Main()' (3 of 41)2/21/2010 7:37:57 PM

Concepts Revisited - C# Nuts and Bolt - Beta2

The error proves the point that you cannot have two different classes, zzz and yyy, containing Main. Only one occurrence of Main is allowed. You always have only one chance of a lifetime. Ditto with Main.
a.cs class zzz { private static void Main() { System.Console.WriteLine("hell"); } } Output hell

The access modifiers are not included within the signature for Main. Even though Main is made private, it is considered as an entry point function, hence hell gets displayed. This function is unique and works as a special case.
a.cs public static void Main() { System.Console.WriteLine("hell"); } class zzz { } Compiler Error a.cs(1,15): error CS1518: Expected class, delegate, enum, interface, or struct

You cannot create a function outside a class or a structure. This rule has to be strictly adhered to even for Main.
a.cs public class zzz { public static int Main() { return; } } Compiler Error a.cs(5,1): error CS0126: An object of a type convertible to 'int' is required

In this example, the function Main has to return an int and we are not returning any value with the keyword return. The compiler tries to convert a nothing into an int and hence the error. This is a generic error that occurs whenever the compiler tries to convert a data type into another and is not successful. (4 of 41)2/21/2010 7:37:57 PM

cs class zzz { public static void Main() { { int i = 8. we should return such a data type or be prepared for an error.cs(6. The function Main should return an int. } i = 90. }} Compiler Error a. Scope Scope.vijaymukhi. We cannot have any two entities of the same name as the compiler will get confused on whether we are referring to the i which is an int or a zzz. defines the region within which a user-defined entity is visible and can be referred to. }} Compiler Error a. but we forgot to do so. as a concept.19): error CS0161: 'zzz.cs public class zzz { public static void Main() { int i. a.cs class zzz { public static int Main() {} } Compiler Error a. Thus never have duplicate names even though at times they are allowed. a.cs(8. zzz i.cs( error CS0103: The name 'i' does not exist in the class or namespace 'zzz' http://www.Beta2 a.htm (5 of 41)2/21/2010 7:37:57 PM .Main()': not all code paths return a value The compiler's error messages need the services of an editor.C# Nuts and Bolt . Thus whenever an entity should return a value. This results in an error.Concepts Revisited .5): error CS0128: A local variable named 'i' is already defined in this scope Twins are always a problem.

We can use a variable of a class before it is declared/created provided the variable has been declared before the class it reads the code of abc. int i = 4.cs class zzz { void abc() { i = 9. } The compiler does not read a . In the first round.cs(6. As i has been created within the inner brackets.cs class zzz { void abc() { i = 9. } public static void Main() {} int i = 4.cs program in one iteration. it is not available to external code thereafter. a. a.C# Nuts and Bolt .Beta2 A variable is visible from the position it is created to the first close bracket. it does not generate any error and compiles successfully.Concepts Revisited . If it did so.1): error CS0103: The name 'i' does not exist in the class or namespace 'zzz' The variable i has been created within the for statement. } public static void Main() {} } Compiler Error http://www. i <= 10. a. i++) { } i = 90. As the first pass had already brought i into existence.vijaymukhi. therefore it can be accessed only within the brackets pertaining to for. } } Compiler Error a. The scope of i is limited to the for {}.cs class zzz { public static void Main() { for ( int i=0. Hence the error. the C# compiler scans the entire code.htm (6 of 41)2/21/2010 7:37:57 PM . In another pass. then the above program would have resulted in an error as the function abc refers to the variable i which has not been created for the moment.

which is already used in a 'parent or current' scope to denote something else i as a variable is created in class zzz and is visible to all members in the class. initialize i to 9 and on the next line we create it.WriteLine(i). } public static void Main() { } int i = 7.WriteLine(i). a.cs(5. } Compiler Error a. Within abc. our compiler is not one of them. void abc() { int i = 10. we have created another local variable but with the same name as first. } int i = 100. System.C# Nuts and Bolt . int i = 4. Some people are born smart. Within the function abc.Concepts Revisited . This turns out to be unacceptable to C# and hence it reports an error. well. a.5): error CS0136: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i'.cs(6.Console. then are we referring to the local i or the parent i? The local i in abc hides or prevents any access to the parent i.cs class zzz { void abc() { i = 9.Console. http://www. The compiler is not aware of i's existence while parsing the first line hence it stops and shows an error.vijaymukhi.Beta2 a.cs class zzz { public static void Main() { zzz a = new zzz().htm (7 of 41)2/21/2010 7:37:57 PM . we. } void pqr() { System.1): error CS0103: The name 'i' does not exist in the class or namespace 'zzz' What works for variables in a class does not apply to functions as well. a. If we are now to refer to i.pqr().

Console.cs class zzz { public static void Main() { int j = 1 .vijaymukhi. creates a variable called j. a. i = ++j . The compiler first reads the line. } } Output 2 A comma works like a semi-colon. The () brackets gain precedence. System. The compiler treats it as two different statements. i now plays two different roles with different scopes in the same class. i will refer to the variable and value defined within zzz.WriteLine(j). Also. Initializing i in abc to 10 hence does not change the value of i in zzz. In function abc.WriteLine(i). Exceptions a.Beta2 i = 1. then initializes it to 1. } } Output 1 The compiler gives no error as the variable j is being used on the same line of its creation.Console.cs http://www. similar to the variable i in class zzz. as there is no variable named i defined in pqr. It does not precede it.C# Nuts and Bolt .cs class zzz { public static void Main() { int j = ( j = 1) . System.htm (8 of 41)2/21/2010 7:37:57 PM . Had it been like in the previous example. The local variable in abc hides the parent variable in its function. an error would have been generated.Concepts Revisited . } } Output 10 100 The program does not generate any compilation error. we are allowed to create a variable named i.

Concepts Revisited .C# Nuts and Bolt .WriteLine("Bye"). a=new yyy(). (9 of 41)2/21/2010 7:37:57 PM . } catch { System. System. } catch (System.Exception().Exception e) { http://www. we are not aware of the exceptions and the types of exceptions it will throw. One way to eradicate this uncertainty is to catch all the exceptions.cs class zzz { public static void Main() { yyy a.Beta2 class zzz { public static void Main() { yyy a. a=new yyy(). try { a. } } Output In Exception When we call a function. } catch { System. try { a. You can do so by not specifying any Exception with catch.Console. It is perfectly legal tender to unspecify the name of the Exception we are trying to catch in the catch. } } } class yyy { public void abc() { throw new"Bye").vijaymukhi.WriteLine("In Exception").abc().WriteLine("In Exception"). System.Console.

Console. } catch (xxx e) { System.ToString()).WriteLine("In Exception").cs(16. Reverse the order of the catches and watch the error disappear. The C# compiler does not permit you to have a catch with no Exceptions followed by a catch with an Exception.Exception().1): error CS1017: Try statement already has an empty catch block The error message is self-explanatory.WriteLine("Bye").com/documents/books/csadv/chap1.Beta2 System. try { a. a.C# Nuts and Bolt . System.Console. } } class xxx : System. a=new yyy().htm (10 of 41)2/21/2010 7:37:57 PM .WriteLine("In Exception" + e.Concepts Revisited . The reason being that the first catch is more generic and it will catch all the Exceptions.Exception { } Output http://www.Console.cs class zzz { public static void Main() { yyy a.vijaymukhi. } } } class yyy { public void abc() { throw new xxx(). This leaves no exceptions for the second } } Compiler Error a. } } } class yyy { public void abc() { throw new System.

Concepts Revisited .8): error CS0160: A previous catch clause already catches all exceptions of this or a super type http://www.C# Nuts and Bolt .abc() at zzz.WriteLine("In Exception" + e. System.Console. } catch (System.Beta2 In Exceptionxxx: An exception of type xxx was thrown. using exceptions it will throw 6 different objects. In the program above. Now.cs(16.vijaymukhi. there is no certain limit to it.WriteLine("Bye"). a=new yyy().ToString()). Earlier if our function returned six different types of errors then the method would return six different numbers. Function abc throws an object that looks like xxx hence the catch traps an xxx object while calling the function. } } class xxx : System.Exception { } Compiler Error a.Exception and contains no Exception We can create hundreds of Exceptions. at yyy. xxx is derived from System. a.Exception. It is child's play to create an exception.Console. } catch (xxx e) { System.Main() An exception is a class derived from System. try { a.Exception e) { System. The output is displayed using the ToString function of the object. } } } class yyy { public void abc() { throw new xxx(). The reason behind introducing Exceptions was to simplify the job of identifying errors.htm (11 of 41)2/21/2010 7:37:57 PM .cs class zzz { public static void Main() { yyy a.WriteLine("In Exception" + e. All these objects are derived from the System.

Main() In finally And if we comment out the throw statement. It is advisable to make it the last catch in the series of catches as if it is the first. } finally { System. at yyy.WriteLine("In finally"). Exceptions are said to be a structured.vijaymukhi.ToString()).WriteLine("Bye"). } catch (System. } } } class yyy { public void abc() { throw new System. It is very similar to having a catch with no at zzz.Console.Concepts Revisited .Exception was thrown. a=new yyy(). it will catch all the exceptions leaving nothing for the other catches. The earlier explanation holds true in this case too. try { a. System.Exception().Beta2 ('System. All modern programming languages support class zzz { public static void Main() { yyy a.htm (12 of 41)2/21/2010 7:37:57 PM .WriteLine("In Exception" + e.Exception') System.Console.Exception: An exception of type System. type safe and a uniform way of error } } Output In ExceptionSystem. Output Bye In finally http://www.Exception e) { System.Exception catches all the exceptions. a.C# Nuts and Bolt .

cs class zzz { public static void Main() { int i = 5/ the statements following the try catch blocks are executed.Beta2 Once an exception is thrown. int i = 5/j. Irrespective of an exception being thrown or not.Concepts Revisited . we simply place the code in finally.C# Nuts and Bolt .cs class zzz { public static void Main() { int j = 0.cs class zzz { public static void Main() { try { int j = 0. a. The code within this block unquestionably is executed. } catch ( System.htm (13 of 41)2/21/2010 7:37:57 PM . an exception is generated at run time.Exception e) { System. control passes to the catch statements.WriteLine("Hi " + e. a. a.Console. } } Compiler Output a. The statements in try following the function that causes an exception. A finally will always be called at the end. the next executable statement is the one following the try-catch block.cs(5. The question here is 'What if we want some code to be called irrespective of whether an exception occurred a not'. It knows that a number cannot be divided by zero and thus stops us in our tracks with an error. are never executed. } } } http://www.ToString()).9): error CS0020: Division by constant zero The C# compiler is very intelligent. int i = 5/j.vijaymukhi. To do so. } } It is however not very smart and in the above case. After executing the catch code.

any unforeseen application error can be caught at run time gracefully. a. at zzz.Console.WriteLine("In Exception" + e. } finally { System.ToString()). } catch (System.C# Nuts and Bolt . } } http://www.Concepts Revisited . } finally { System.Exception().WriteLine("Bye"). In this class zzz { public static void Main() { yyy a.Beta2 Output Hi System.WriteLine("In finally" ).DivideByZeroException: Attempted to divide by zero. } } } class yyy { public void abc() { //throw new System. a=new yyy(). } catch (System. } public void pqr() { throw new System.vijaymukhi. try { a.Console.Exception e) { System.Console.Exception().htm (14 of 41)2/21/2010 7:37:57 PM .ToString()).WriteLine("In inner try" + e.WriteLine("In inner finally").Exception e) { System. } All exceptions thrown at run time can be caught using try-catch. try { a.pqr().

8): error CS1518: Expected public namespace vijay { } Compiler Error a. Finally waits for the try-catch to complete its task. all compilation units are compiled together and hence can depend on each other. Every time you execute a function.cs public class zzz { public static void Main(string[] a) { using System.cs(5.7): error CS1003: Syntax error.Main() In inner finally Bye In finally Interesting !!! Basically. Moreover. enum. within a catch block. you can have another trycatch which should be considered only when there is a function call in the catch. a.pqr() at zzz.Beta2 Output In inner trySystem. the outer catch is not called.vijaymukhi. '(' expected http://www. A C# program can consist of one or more compilation units. Conversely.C# Nuts and Bolt . A source file is defined as a compilation unit. delegate. } } Compiler Error a. that function may throw an exception. at yyy. Hence.Exception: Exception of type System. The catch that catches it is the inner catch and not the outer catch.cs(1. a. So you can place the function call in a try-catch block. you are allowed to have as many try-catch blocks in your code as your heart's desire. the order is from the inner to the outer resulting into seeing bye before last. or struct A namespace is explicitly public and we are not allowed to specify any access modifiers to it. the finally for both the trys is called. abc does not throw any exception but pqr does. Namespaces C# programs are organized using namespaces which provide an organizational system for presenting programs. In the program.Exception was thrown.Concepts Revisited . interface.htm (15 of 41)2/21/2010 7:37:57 PM . When we try and compile a C# program.

In the program. it can now be replaced with z.a2. Wherever we write a1.13): error CS1026: ) expected The using directive can only be placed at the beginning of the program.yyy. z1 stands for only the namespace name and thus we have to specify the name of the class. using z1 = a1.yyy.Concepts Revisited .C# Nuts and Bolt . z1. we have created two aliases -. } } namespace a1.a2.Beta2 a.a2.yyy c. public class zzz { public static void Main(string[] a) { z b. We are provided with some help in the form of an alias in the using directive. the full name of the class yyy. It cannot be used anywhere else.cs(5.cs public class zzz { public static void Main(string[] a) { } } namespace n1 { class yyy { } } namespace n1 { class yy { } } Namespaces are open-ended.cs using z = a1. An http://www. we cannot change the name of the second class to yyy as we cannot have the same name in the same namespace.vijaymukhi.a2 { class yyy {} } Using nested namespaces can make our names too large. the net result here will be that the namespace n1 will contain both classes -.htm (16 of 41)2/21/2010 7:37:57 PM . The scope of using is the current source file and it does not influence any other programs included while compiling.yy and yyy. a. a.z and z1.

cs using z = a1. a.C# Nuts and Bolt . a. it will blindly replace it by a1. namespace a1.a2.7): error CS0576: Namespace '' already contains an alias definition for 'z' You cannot have a class name and an alias with similar names as this will confuse the compiler.vijaymukhi. Hence the error. using z = a1. public class zzz { public static void Main(string[] a) { } } namespace a1.Beta2 alias is conceptually very simple.a2. class yyy {} } namespace a3 { class ddd : z { } } Compiler Error a.yyy.a2.13): error CS0246: The type or namespace name 'z' could not be found (are you missing a using directive or an assembly reference?) The class zzz remains the same as before.htm (17 of 41)2/21/2010 7:37:57 PM .yyy.a2 { class yyy {} } http://www.a2.cs(8.yyy.a2 { using z = a1.Concepts Revisited .a2.yyy.cs namespace a1.a2 { class yyy {} } class z { } Compiler Error a. Wherever C# sees a z. The scope of z is only limited to namespace a1. An alias created in one namespace or compilation unit is simply not available to another.cs(1.

cs using z = a1.a3 but within the namespace a3 it is temporarily given a value of a2. class ddd : z.Concepts Revisited .cs(1.cs using z = a2.vijaymukhi. Thus the error reads a2.cs(1.yyy and not a2.a3 http://www.C# Nuts and Bolt . If we comment the inner alias.yyy. If the compiler cannot resolve it. namespace a3 { class ddd : z { } } Compiler Error a.yyy. a.htm (18 of 41)2/21/2010 7:37:57 PM . a3. namespace a2.a3 { } namespace a3 { using z = a2.Beta2 namespace a3 { class ddd : z { } } Here we do not get any namespace error as we have placed the alias in the global or default namespace. a.11): error CS0246: The type or namespace name 'a1' could not be found (are you missing a using directive or an assembly reference?) a.a3.cs namespace a2. Here C# is not knowledgeable of a1.a3. It is available to all namespaces in this source file only.11): error CS0246: The type or namespace name 'a1' could not be found (are you missing a using directive or an assembly reference?) C# checks the namespace alias and tries to resolve it to a sensible entity. the compiler evaluates z to be a2.15): error CS0234: The type or namespace name 'yyy' does not exist in the class or namespace 'a2' (are you missing a using directive or an assembly reference?) The namespace alias can be hidden by another namespace alias. Globally z is a2. it gives an error.yyy { } } Compiler Error a. or a3. both match and hence the class zzz { public static void Main() { aaa a.htm (19 of 41)2/21/2010 7:37:57 PM . using z2 = z. using z1 = a2.1): error CS0104: 'aaa' is an ambiguous reference The reason we get an error is because in Main. All of them have to be self contained with no dependencies.12): error CS0246: The type or namespace name 'z' could not be found (are you missing a using directive or an assembly reference?) The above error comes in as C# interprets only one using at a time. As both namespaces a2 and a3 have a class aaa. This means that C# turns a blind eye to the other using's.Concepts Revisited .C# Nuts and Bolt . aaa can either become a. using a3. } Compiler Error and there is no ambiguity.a3.cs(8. will give us only warnings as duplicate usings are not flagged as an error.a3. } } namespace a2 { class aaa {} } namespace a3 { class aaa {} } Compiler Error a. a.cs using a2.cs(7.Beta2 { } namespace a3 { using z = a2. The order of usings is of no relevance. The class aaa now becomes a3.cs namespace aa { namespace bb { class cc{} http://www. We cannot incorporate an alias within another. Changing using a2 to using a3.

7): error CS0101: The namespace 'aa. reference and output and finally local variables. initially assigned and initially unassigned. The C# compiler guarantees that the variable will never ever have a value other than what is permitted by its data type. The name of a variable is always decided by consulting an astrologer.C# Nuts and Bolt . } public static void Main() http://www. say.vijaymukhi.Concepts Revisited . that informs C# about the values that can be stored in it. In the same way every variable has to have a data type associated with it. array. They cannot be stored in your or my pockets. byte [] weight. an initially unassigned variable does not. ref int i5. int i2. so it finally becomes aa. This is because you always need someone to take the flak for your programs not working.Beta2 } } namespace' already contains a definition for 'cc' We cannot have a class cc in namespace aa. Variables Variables are always stored in memory as they represent a memory location. C# has so far created seven types of variables for us. instance. void abc(int i4.htm (20 of 41)2/21/2010 7:37:57 PM . in this book. Let us learn something more about each one of them. i6=10. in your life let your loved ones decide! Every human being has to have some properties associated with him or her. C# is very finicky about what you store in it. If you have been counting. Big brother is always watching over your shoulder! Variables in C# fall in two states. The namespaces are { class cc{} } Compiler Error a. parameter types like can be viewed as a namespace aa containing a namespace One of these could be. Complex words but a simple a. These are: static. similar to people who are very finicky about the clothes they wear. The fully qualified name for the existing class cc is aa. so why not blame it on a poor choice of variable names? Remember. An initially assigned variable has a defined value. we decide names of variables. out int i6) { int i7 .cs public class zzz { public static int as it already exists within the namespace bb under namespace aa. Thus namespace aa.

Concepts Revisited .C# Nuts and Bolt . we cannot read its value in the function. The programmer is powerless to kill an instance variable. An instance variable comes to life only when an instance of that class is created using the keyword Within a structure. Array members behave in the same way as instance members so we see no point in explaining the same concept using different words and consuming more paper and cutting more trees. The only change made was that the word instance was replaced by static. we have no control over death.cs public class zzz { public static void Main() http://www. We cannot initialize an out variable at the time of invocation but must initialize it at the time of exit. The instance variable dies when there are no more references to the object. Variables like i5 and i6 are ref and out respectively due to the modifiers. Thus. All other variables created by themselves in a class are called instance variables. The keyword 'this' in the constructor of a struct is an out parameter. A static variable is born at the time the class is loaded and is alive and kicking as long as the program runs. Parameters by default are passed by value like i4.Beta2 { } } First. A reference variable has to be assigned a value on invocation unlike the out parameter. In languages like C#. The out parameter is similar to the ref in many aspects. It simply stands for a reference to the original object. as it is initially unassigned. it is called a local variable. i2 is an instance variable as it is created outside a function and i3[0] is an array element if we initialize the array member using new. A local variable is never initialized and thus has no default value. instance variables die whenever C# feels that it has no use for them. A value parameter is assigned a value at the time of function invocation. An instance variable is initially assigned which means that it gets the default values of its data type. Also. has the same life-time as the structure. We apologize but had to have the above explanation spread over at least three lines without repeating ourselves. The above line was simple cut and paste from the above paragraph.htm (21 of 41)2/21/2010 7:37:57 PM . A local variable is created at the open { and dies at the close }. Good writers can waste many words writing gibberish. an instance variable created in a structure. A static variable is initially assigned which means that it gets the default values of its data type. Thus. like in real life. If the structure is initially assigned so are the instance variables and vice versa.vijaymukhi. A reference variable unlike a value variable does not create a new memory location. a quick recap. the keyword this is passed by reference. A structure is always created on the stack. as i7 is created within a function. i1 is a static variable due to the keyword static. Also. It represents the original memory location of the object in the function invocation. Both have the same value as the underlying variable. a. The variable is alive at the open brace { and dies at the close brace }.

System. } } Compiler Error a. From the compiler vocabulary. static. } Compiler Warning a. the above error is reported.cs(6. } } Compiler Error a.C# Nuts and Bolt . At times.i' is never used All that we get from C# is a benign warning saying that we are not using the variable i. This is perfectly legal in C#. the default value is null. int i. initializing a variable is not similar to using a variable.cs public class zzz { public static void Main() { i = 10. it would not have resulted in an error.Console.cs(5.12): warning CS0169: The private field 'zzz. For a reference variable. } static int i.Concepts Revisited .htm (22 of 41)2/21/2010 7:37:57 PM a.cs(7. As a repetition. the garbage collector responsible for the murder of variables may decide to terminate it before the close } as it is not being referred to.Beta2 { int i. Had i been an instance variable and created even after Main. a.WriteLine(i).cs public class zzz { public static void Main() { i = 10. it is all at the mercy of the great C#. http://www.1): error CS0103: The name 'i' does not exist in the class or namespace 'zzz' We cannot refer to a variable before it is created and if we do so. instance and array members all have default values.26): error CS0165: Use of unassigned local variable 'i' A local variable is initially unassigned. Thus a variable may die an earlier death.

The value we supply to the keyword new in square brackets is the size of the array or as termed in the array world."). Null is not even a space and hence the two dots have nothing separating them. This value is defined as length and must be positive.Beta2 a.. Unfortunately. The warning very clearly informs us that C# has detected a variable i.12): warning CS0649: Field 'zzz. a rose by any other name is perceived to smell as sweet no matter what name you call it by. An array element is accessed using a number in square brackets known by a more difficult name -. In our view. } } http://www.Concepts Revisited . Null means no value and cannot be displayed. all the members of an array must have the same data type called the array type. } class yyy { } Compiler Warning a. The array dimension is represented by a value. which must be larger than or equal to zero.cs class zzz { public static void Main() { int [] a. Arrays An array is also known as a data structure in formal computer science books.C# Nuts and Bolt .com/documents/books/csadv/chap1. In case of more than one index. and will always have its default value null Output .i' is never assigned to. a rank specifier. i is a variable of a reference type.a computed index.Console. a. we call it a multi-dimensional array.cs public class zzz { public static void Main() { System. } static yyy i.cs(7. It does not have a compile time value but receives a value at run time. An array will normally contain more than one variable called the elements of the array.WriteLine(".htm (23 of 41)2/21/2010 7:37:57 PM .vijaymukhi." + i + ". a = new int[]. In Book 1. we have seen only single-dimensional arrays or arrays of rank one. which has not been initialized to any value hence it will be null.

Once an array has been created.Concepts Revisited . its length cannot be altered any Nuts and Bolt . the size must be specified. Everything is fixed.Beta2 Compiler Error a. however. } } It is valid or perfectly legal to give a size of 0. } } http://www. a. } } Output Exception occurred: System. C#.14): error CS1586: Array creation must have array size or array initializer During the act of creating an array. is extremely concerned about going beyond the scope of the array. a[11] = 10. IndexOutOfRangeException was thrown. at zzz.Main() If you exceed the bounds of an array. We are not allowed to resize the dimensions. a.IndexOutOfRangeException: An exception of type System. in other words. a = new int[1]. you will not get any compile time error but unfortunately you land up to a run time error.vijaymukhi. The array.cs(6. a = new int[10]. has no practical value if you do so.cs class zzz { public static void Main() { int [] a. The exception thrown can be caught by your program. a = new int[0].cs class zzz { public static void Main() { int [] a.htm (24 of 41)2/21/2010 7:37:57 PM . a.cs class zzz { public static void Main() { int [] a. a = new int[10].

Concepts Revisited .8}. In the third case. In the same way. } } There are many ways to skin a cat.8): error CS0029: Cannot implicitly convert type 'int' to 'string' The conversion rules applying to data types also apply to an The first array remains inaccessible in the program as array a has been redefined as one element array.4.24): error CS0178: Incorrectly structured array initializer http://www. In the case of b.Array. int [] c = {0.cs class zzz { public static void Main() { int [] a = new int[3] {0. } } Compiler Error a. The array a has been initialized the long way where we have specified the keyword new with the size of the array along with the initial values in {} braces. which is an abstract class. Once an array has been created it cannot be resized later. we've skipped the length and directly supplied three values.4. All arrays are derived from System.cs(5. } } Compiler Error a.8}.4.4. a. The length of this array becomes 3.cs class zzz { public static void Main() { string [] a.htm (25 of 41)2/21/2010 7:37:57 PM . we can initialize an array in different ways. a[1] = 9.C# Nuts and Bolt .8}.cs(7.8}. a.vijaymukhi. a = new string[10]. we have done away with the new altogether. a.cs class zzz { public static void Main() { int [] a = new int[5] {0. int [] b = new int[] {0.

C# Nuts and Bolt . int[] b = new int[j].Length). a. System.Console.htm (26 of 41)2/21/2010 7:37:57 PM . int [][. } } Output 3 Irrespective of what the documentation has to say. is a three-dimensional array consisting of two-dimensional arrays which in turn are of single-dimensional arrays each.2]' and then initializing the individual members. It is similar to writing 'b = new int[5. a. The foreach construct then displays every member in the array. System. you are allowed to use a variable to initialize an array. a.vijaymukhi.Write(i + " "). 1}.. foreach ( int i in b) System. {8. The value stored in each element will be an integer. } } Output 10 0123456789 We have created a two dimensional array having a length of five for the innermost rank and 2 for the outermost rank.Console.] a. {2. The member Length in System.Concepts Revisited . {6. 7}. 5}. {4.][.Length). They have to be the same. Not one more. 3}. 0]=0.WriteLine(b. 1]=1 etc.cs class zzz { public static void Main() http://www. b[0.Array.cs class zzz { public static void Main() { int j = 3. b[0. inherited by b displays 10 as the total number of members in the array are 5*2.WriteLine(b. 9}}. not one less.Console.Beta2 We cannot create a larger array and supply fewer values in the {}] b = {{0.cs class zzz { public static void Main() { int[. We have used the variable j to create b.

htm (27 of 41)2/21/2010 7:37:57 PM .vijaymukhi. In the first for. http://www. i++) { Console. To declare a managed array the rank specifier precedes the variable's identifier a. public class zzz { public static void Main(string[] a) { byte[][] s = new byte[5][].cs(5. a. a.C# Nuts and Bolt .Length). Each of these 5 members can be made up of an array of any size. the first member.cs using System.WriteLine("Length of row {0} is {1}". we are initializing s[0]. ']' expected The array square brackets must come before the name of the variable and not after.WriteLine(s. in the second round. The above line would be a valid C syntax.cs(5.6): error CS0650: Syntax error.8): error CS1003: Syntax error. Thus.cs(5. s is a jagged array with 5 members. s[1]. In the second iteration of the for. } } } Output 5 Length of Length of Length of Length of Length of row row row row row 0 1 2 3 4 is is is is is 3 4 5 6 7 A jagged array has a variable number of members.Length. These are issues of syntax and do not follow any coherent pattern. s[1] now points to an array of bytes having 4 members. System. i < s. i++) { s[i] = new byte[i+3].Concepts Revisited .Length displays 4.Beta2 { int b[].cs using System. i < s. } for (int i = 0.Length). bad array declarator. for (int i = 0.Console. to an array of bytes which is 3 large.7): error CS1525: Invalid expression term ']' a. } } Compiler Error a. s[i].

System.}. an array is passed by reference and any changes made through z will reflect the values in the original array.4}.3. zzz b = new zzz().Console.6.9} }. a. http://www.8. Change the function abc by adding the params keyword.WriteLine(a[1]).6.C# Nuts and Bolt .com/documents/books/csadv/chap1.htm (28 of 41)2/21/2010 7:37:57 PM .Beta2 public class zzz { public static void Main(string[] a) { int[][] n8 = new int[2][] { new int[] {2.WriteLine(z[1]). This can be done in two ways. } public void abc( int [] z) { System. b.8} }.abc(a).Concepts Revisited . } } And one more example for the road to ponder on.vijaymukhi. However.3. new int[] {5. int[][] n9 = new int[][] { new int[] {2. even though the changes get incorporated. z[1] = 100. as we never gave it a name. This proves that a params keyword is nothing but an array parameter.cs class zzz { public static void Main() { int [] a = {1.Console. b.3}.5}). public void abc(params int [] z) and the above program runs exactly the same as earlier. This is as shown below. There is no way on earth the function can ever know or care on the method you have adopted. } } Output 3 5 100 You can give an array as a parameter to a function. there is no way of accessing the int[]{4. either by stating an array name explicitly or by creating an array at the time of creating the function. In the second case. new int[] {5.7. This shows the levels of complexities that you can delve in.

C# Nuts and Bolt .htm (29 of 41)2/21/2010 7:37:58 PM .com/documents/books/csadv/chap1. a major difference between an array and a params parameter.3}.abc(a). If the data type is an array. System. zzz b = new zzz().abc(a. params int [] z) { System.Console.vijaymukhi.a).6}.Concepts Revisited . so be it. These are converted into an array. } public void abc(int [] y. We can either pass an array or as many individual ints we desire to the second parameter. we can also use the modifiers of ref and out.WriteLine(a[2]). a). we have to recreate an array within the function despite having initialized it earlier. } public void abc(out int [] z) { z = new int[3]{1.WriteLine(z.3}. A params parameter can also be null as in the first invocation of abc. b. If the parameter is an array then no other data type can be provided other than an array. } } Output 6 With an array.Beta2 a.Length). zzz b = new zzz(). a. An out modifiers demands new entities to be created inside the function. } } Output 0 2 There is.cs class zzz { public static void Main() { int [] a = {1.Console. a params modifier is more flexible as we are allowed to give individual data types. b.cs class zzz { public static void Main() { int [] a = {1. Even a single int has to be passed as an array. you must create it and if we do not initialize it. the value is automatically http://www. However.4. b. The difference between them is that in the out modifier.

a. } } http://www. } } Compiler Error a.Console. we are creating an array of three ints and supplying values to initialize only two of them. a.2}.22): error CS0178: Incorrectly structured array initializer Whenever we initialize an array. System. Apart from this distinction. In the above case the default value is zero as the type of the array is an int. that the last member a[2] would be initialized to zero. } } Output 0. the size of the array stated in the new and the values to be initialized must be the same in number. We thought. wrongly so. In the above case.WriteLine(a[0] + ".htm (30 of 41)2/21/2010 7:37:58 PM . if the array is not initialized. The compiler proved us wrong by giving us an error instead." + a[2]). the behaviour followed is like a normal ref entity." + a[1]).C# Nuts and Bolt .cs class zzz { public static void Main() { int i = 0.Console.cs class zzz { public static void Main() { int [] a = new int[3]. int [] a = new int[3]{i++. a. then it takes the default values of the data type.vijaymukhi. a variable needs to be initialized before using it but in case of an out.cs(5. Like any normal object. System.cs class zzz { public static void Main() { int [] a = new int[3]{ Revisited . An array can be initialized to a null if need arises as a null may mean no value.WriteLine(a[0] + ".i++}." + a[1] + ". This also means that someone somewhere gave it no value.0 An array type is always initialized to the default value of its type.i++.Beta2 initialized to zero.

0 We create an array of ints and initialize them to objects that smell like yyy's.htm (31 of 41)2/21/2010 7:37:58 PM . class zzz { public static void Main() { yyy a1 = new yyy(1).0." + a[1] + ".1.0.Exception().b1. } public static implicit operator int ( yyy z) { System. a.i == 10) throw new System.Concepts Revisited . There is no problem in doing so as the operator int converts the yyy object into an int.WriteLine(a[0] + ".C# Nuts and Bolt .0 0. } } Output op 1 op 10 0." + a[2]). } catch ( System.c1}. yyy c1 = new yyy(100).i.2 No astonishing facts for a function! Same rules apply here too.Beta2 Output 0. int [] a = new int[3] .WriteLine(a[0] + ". public yyy(int j) { i = j. return z.Console." + a[2]). } System. Each initialization is done independent of each other and starting from left to right.WriteLine("op " + z.Exception e) { System." + a[1] + ".i). } } class yyy { public int i. try { a = new int[3]{a1.Console.Console.vijaymukhi. yyy b1 = new yyy(10). if ( z. No side effects at all.

we throw an exception. by default. They are to be initialized later and individually. In this way.cs(5.C# Nuts and Bolt . do the following. one size does not fit all ever.cs class zzz { public static void Main() { int [][] a = new int[3][]. The array members have to be initialized as the initialization statement is in a try block. as follows. If we fail to do so. however. Due to this.Console. a[0] contains only one int and the second a[1] has 10 ints. initialized to zero before they get their new values.25): error CS0178: Incorrectly structured array initializer a. or else an exception is thrown. System. a. } } Output 3 1 10 The size of the array a is 3 and it contains three members which are an array of class zzz { public static void Main() { int [][] a = new int[3][2].WriteLine(a. We are forbidden to initialize a sub array at the time of creation. The first one. hence the error. we get an 'uninitialized variable error'.cs(5. a[1] = new int[10].Concepts Revisited . a.Length + " " + a[0].cs(5.vijaymukhi.Length ). the compiler at run time undoes the initialization of array member a[0] to 1 and it falls back to the earlier default value of zero. The array members are.Length + " " + a[1]. In life also. This is the first task it performs on exceptions.htm (32 of 41)2/21/2010 7:37:58 PM . The array access element must not be less than zero or greater than the size of the array.26): error CS1525: Invalid expression term ']' Ha Ha Ha!!! We are overjoyed as we confused the compiler to no end.26): error CS1002: . a[0] = new int[1]. Not permitting the initialization of sub arrays at the time of creation brings in flexibility as we can now initialize each of them to any size we wish rather having the same size. http://www. } } Compiler Error a. Each of the 10 arrays being reference types is initialized to a value null. We cannot.Beta2 For the object b1 whose instance variable i has a value 10. One error on our part and the compiler bought the entire cavalry out by giving us three errors instead. expected a. An initialization statement of int [] a = new int[10][] creates an array of ten members and each of them in turn is considered to be an array. we fool the compiler into doing our bidding.

Finally."hell"}. it uses this array as the params parameter to the function.WriteLine(i). a. a. if we write int [. If the function is called with no parameters.Beta2 A rectangular array is an array of arrays where all the sub arrays have the same length. } } There is nothing to feel sorry about when we create an empty array.cs class zzz { public static void Main() { int [] a = new int[0].vijaymukhi.2.Concepts Revisited .com/documents/books/csadv/chap1. In the expanded form. Thus. a. then the array becomes an empty int i = 10. It is the compiler's job to create an array of the same data type and width and then initialize the members with the values stated as parameters.cs class zzz { public static void Main() { zzz a = new zzz()."hell"). } public void abc(object a) { System.Console. a = 100.5] we are only creating one array in all and also it uses only one statement.] a = new int[10. we are creating one main array and 10 sub arrays. A similar thing happens with a value parameter. However.htm (33 of 41)2/21/2010 7:37:58 PM .2. if we had a simple function abc (params object [] a) and we called the function abc as abc (1.Console.C# Nuts and Bolt . which then is converted into an actual array. we do not use an array but pass the parameters individually. then an array would be created as new object[] { 1. Compare and contrast it with the above and choose the one you are most comfortable with. If we write new int[10][] and initialize the sub arrays to new int[5]. System. Parameter arrays When we use a params parameter in its normal form. It is finally a personal decision. the data type to be specified must be of a type that can be directly or implicitly converted to the parameter array type. This is more efficient than a multi dimensional array.WriteLine(a). } } http://www. An array is created after all.

Beta2 Output 10 10 When calling the function abc.cs class zzz { public static void Main() { int [] a = new int[10]. to an object using a method called boxing.htm (34 of 41)2/21/2010 7:37:58 PM . If you do not believe us. which is an instance of class object. a. In the above case. if we do not specify ref or out.Console. then there is no way in hell that the value of i can be changed within the function.C# Nuts and Bolt .2] = 10. It is unfortunately very selective in the type of error handling and some common errors go undetected. Main is the last function in the world to complain.cs(6. In spite of it being a reference type.WriteLine("hi"). The error tells us that the compiler checks whether we have given the right number of indices but it does not check whether we have exceeded the bounds of the expected '1' A one.1): error CS0022: Wrong number of indices inside []. we have upgraded our value parameter.Concepts Revisited .or a single-dimensional array can only have one indice and not 2. a[1. } } Compiler Error a. The Other Odds and Ends a. Here we placed it in a structure.vijaymukhi. i. All the rules binding other functions apply to Main also.cs struct zzz { public static void Main() { System. cast i to an object explicitly and yet nothing changes. All this is part and parcel of the array error handling enforced by the compiler. will not reflect any changes made within the function abc in Main. a. You cannot place functions anywhere else in your program. http://www. } } Output hi There is no rule in the world that mandates the Main function to be placed only in a class.

Concepts Revisited . new or override. This results in an error. so shouldn't it be acceptable? The compiler however does not think so. only one love.cs( a.C# Nuts and Bolt . } } class yyy { public int aa { get {return 0. } } Compiler Error a.} set {} } public void abc( ref int b) { } } http://www. a.cs(10.aa = 10.htm (35 of 41)2/21/2010 7:37:58 PM .aa). but wait a minute. we have two functions called Main.Console. Always follow the simple dictum.Main()' In the above program. } } class yyy : zzz { public new static void Main() {' has more than one entry point defined: 'zzz. We cannot use the modifiers virtual.exe' has more than one entry point defined: 'yyy. so only one function called Main! a. Hey.cs class zzz { public static void Main() { System. Main being repeated twice in separate classes.WriteLine("hi in zzz"). as the function is static.Console.24): error CS0017: Program 'a. they are in separate classes.cs class zzz { public static void Main() { yyy a = new yyy().Main()' a.WriteLine("hi in yyy").Beta2 a.20): error CS0017: Program 'a. a.vijaymukhi. It does not like this specific function.

aa).cs class zzz { public static void Main() { yyy a = new yyy().Console. We are allowed to change the property value. a. the program goes into an indefinite loop. } } class yyy { public int = 0. System. } return j.htm (36 of 41)2/21/2010 7:37:58 PM .C# Nuts and Bolt . accessors.vijaymukhi. } } } The above program does not give any compiler error. a. it's a duck. All the restrictions of static apply to static properties too. System. A set accessor is like a function that returns void and it has an implicit parameter value. // aa++ k = 1.cs class zzz http://www. This is regardless of the fact that by using the value of variable we ensure that the statement aa++ is executed only once. Only a storage or memory location can be passed as a ref or an out parameter. A property looks and feels like a variable but it is actually a series of functions or to be technically correct. public int aa { get { System.Concepts Revisited .Beta2 Compiler Error a.11): error CS0206: A property or indexer may not be passed as an out or ref parameter If it walks like a duck. The get accessor must terminate either in a return or a throw statement.aa = 10.WriteLine(a. if ( k == 0) { aa = aa + 1. quacks like a duck.Console.Console. A property is not allocated any memory and thus cannot be used wherever a variable can be used. a. } set { j = value. within a property.WriteLine("set " + j). Control cannot flow off the accessor body at the end.cs(7.WriteLine("get " + j). If you do so.

return j. Here in the get accessor of property aa. One proof lies in the above program.WriteLine(a. public int aa { get { System. A property is identified by a name. a. } set { j = value.WriteLine("get2 " + j).WriteLine("get1 " + j). No indefinite loop but crazy answers!! The long and short story for that matter is.Console. we are calling the set accessor by giving the statement aa = 4. do not call the get or set accessor with a property directly. a.aa).k = 0. an indexer by its signature. System. An indexer is similar to a property other than the fact that the indexers. accessors take or accept parameters.Concepts Revisited .vijaymukhi.aa = 10.WriteLine("set " + j ). aa = 4.Console.Console.htm (37 of 41)2/21/2010 7:37:58 PM . System. } } class yyy { public int j. System. } } } Output set 10 get1 10 set 4 get2 4 4 We all have been dumb many a times in life.Beta2 { public static void Main() { yyy a = new yyy().cs class zzz { public static void Main() {} } class yyy { Nuts and Bolt .

vijaymukhi. an indexer cannot be static.cs(8. we surprised the compiler. A property has no such luck and no parameters at all but the set receives the implicit parameter value. the error http://www. similar to an indexer.cs namespace aaa { int i.cs(3.Beta2 public static int this[int i] { get {return 0. In an interface.} set {} } } Compiler Error a. the only job of an indexer is to declare the signature. A get and a set accessor share the same parameter list that the indexer has. They decide the signatures of functions. } } } Compiler Errors a.1): error CS0118: 'aaa' denotes a 'namespace' where a 'class' was expected Wouldn't you be surprised if you see a tiger instead of a dog? Similarly. We are not allowed to place methods and fields directly in a namespace or outside a namespace. follow the rules built in them. They cannot carry code. These are the regulations to be followed in the compiler world.cs namespace aaa { public class zzz { public static void Main() { aaa a. a. If we give the name of a property instead of a class. a.cs(7.1): error CS0116: A namespace does not directly contain members such as fields or methods The compiler is very particular about what you place where. } Compiler Error a.htm (38 of 41)2/21/2010 7:37:58 PM .Concepts Revisited . so that other people who implement error CS0106: The modifier 'static' is not valid for this item Unlike a property.C# Nuts and Bolt . Interfaces are smart. Nothing stops us from placing them in a class. A property cannot be accessed like an array or by element access. All that they do is boss around. It expected a class/type name and instead comes by the name of a namespace. indexers etc. The above error is a generic error.

two using's are out whether they are the same or different. a.11): error CS0134: Cannot use qualified namespace names in nested namespace declarations We can have namespaces within namespace with nary a nod from the compiler.cs new class zzz { } Compiler Errors a.C# Nuts and Bolt .1): error CS1530: Keyword new not allowed on namespace elements You cannot use new on namespace elements like class or struct.1): error CS1529: A using clause must precede all other namespace elements We all wanted to come in class but using always beat us to the draw. What we cannot have is a qualified namespace within another namespace.ccc { } } Compiler Error a.cs using aa = System.cs(2. Compiler Error a.vijaymukhi. We have no choice but to start our code with the using clause.7): error CS1537: The using alias 'aa' appeared previously in this namespace The compiler hates seeing two of anything even though they are the same and cause no trouble. A single error to take care of multiple possibilities.cs(3. we must. Compiler Error a. but the message would change. Why? Ask the designers of the language. Thus. http://www.Concepts Revisited .Beta2 number will be the same. The generic rule clearly states that a CS0118 error number is emitted whenever the compiler gets something that it does not expect. a.cs(4. We are not allowed to even change our mind. This is because we create them in a global namespace.cs class zzz { } using a.cs(1. a.cs namespace aaa { namespace bbb. This is a rule imposed upon us by the top brass and obey. using aa = System.htm (39 of 41)2/21/2010 7:37:58 PM .

Concepts Revisited . The compiler doesn’t show any errors.cs public class zzz { int a[2]. a. Try using a new expression instead. The {} brackets are to be used exclusively with arrays only. 3. We cannot use the {} brackets to initialize an array within an array. a.WriteLine(s).cs( The {} can only be used for a single dimensional array.26): error CS0623: Array initializers can only be used in a variable or field initializer. a. Try using a new expression instead. } Compiler Error a. The array notation can only be used with the array data type.cs class zzz { int i = {1}.Beta2 a.cs(3.vijaymukhi. For that we have to use the keyword new instead. System.cs class zzz { public static void Main() { string s = @”h i”.9): error CS0622: Can only use array initializer expressions to assign to array types.C# Nuts and Bolt . ending the string there. } Compiler Error http://www.Console. The single change is that you can press enter and move to the next line. {4}}.htm (40 of 41)2/21/2010 7:37:58 PM . } Compiler Error a. } } Output h i The @ sign lets you start a string with ".cs class zzz { public int[] a = { 2.

C# in this case looks a lot like Java.C# Nuts and Bolt . This is before the name of the array. http://www. We failed to give the int variable a name and hence got saddled with an error.cs(6. The array brackets must come before the name of the variable and we are not allowed to state the size of the array within them either. To declare a managed array the rank specifier precedes the variable's identifier There is lots that the C# language has copied from C and C++ and along the way.vijaymukhi.cs class zzz { public static void Main(string a [] ) { } } Compiler Error a.htm (41 of 41)2/21/2010 7:37:58 PM .cs(3.cs(3. bad array declarator. not after. Thus it requires the name of a variable that will contain the individual values of the collection object. All this worked very well in C/ God alone knows why?! a.Concepts Revisited . a. [].34): error CS1552: Array type specifier.Beta2 a.cs class zzz { public static void Main() { int[] a = {1. it has changed the syntax of a few in the language.14): error CS0230: Type and identifier are both required in a foreach statement The foreach has a certain syntax and it lets you iterate over an object.2. foreach (int in a) { } } } Compiler Error a.6): error CS0650: Syntax error. must appear before parameter name Array brackets [] can only be in one place.3}.