Anda di halaman 1dari 259

R.

srihari
Introduction Chapter 1 : What is this .NET all about ? Chapter 2 : Visual Studio .NET C# Language

.NET

Chapter 3 : Your first C# program Chapter 4 : C# : Syntax and Language Essentials Chapter 5 : Datatypes Chapter 6 : Object Oriented Programming using C# Chapter 7 : Properties in C# classes Chapter 8 : Namespaces

Windows Programming using C# Chapter 9 : WinForms Chapter 10 : Simple MessageBox application Chapter 11 : Basic File Operations Chapter 12 : Retrieve Html content from any web site Chapter 13 : Application Configuration Files Chapter 14 : Debugging in VS.NET

Database Operations Chapter 15 : Accessing Database Chapter 16 : Basic Database operations Chapter 17 : DataSet - how and where to use ? Chapter 18 : More about DataTable and DataRow classes. Exception Handling Chapter 19 : Exception Handling in .NET Framework Chapter 20 : .NET Exception Classes Chapter 21 : Traditional Visual Basic error handling Chapter 22 : Writing custom exception classes using C#

XML Files Chapter 23 : Introduction to XML Web Development Chapter 24 : Introduction to HTML Webservices & Remoting Chapter 25 : Introduction to Webservices Best Programming Chapter 26 : Coding Standards & Best Practices Chapter 27 : Design Patterns Advanced C# Programming

Chapter 28 : Generics in C# Enterprise Servers Chapter 29 : SQL Server Chapter 30 : SharePoint Server Chapter 31 : BizTalk Chapter 32 : Commerce Server Chapter 33 : Content Management Server

Future Technologies Chapter 34 : ObjectSpaces Chapter 35 : Whidbey Chapter 36 : Indigo Chapter 37 : WinFS Chapter 38 : Yukon

What is .Net ? It is a platform neutral framework. Is a layer between the operating system and the programming language. It supports many programming languages, including VB.Net, C# etc. .Net provides a common set of class libraries, which can be accessed from any .net based programming language. There will not be separate set of classes and libraries for each language. If you know any one .net language, you can write code in any .net language!! In future versions of Windows, .net will be freely distributed as part of operating system and users will never have to install .net separately. What is Not ? .Net is not an operating system. .Net is not a programming language. ".Net is a framework" Are you confused by this definition? Well, that is OK. It is really confusing! We cannot define .net as a 'single thing'. It is a new, easy, and extensive programming platform. It is not a programming language, but it supports several programming languages. By default .net comes with few programming languages including C# (C Sharp), VB.Net, J# and managed C++. .Net is a common platform for all the supported languages. It gives a common class library, which can be called from any of the supported languages. So, developers need not learn many libraries when they switch to a different language. Only the syntax is different for each language. When you write code in any language and compile, it will be converted to an 'Intermediate Language' (MicroSoft Intermediate Language - MSIL). So, your compiled executable contains the IL and not really executable machine language. When the .Net application runs, the .Net framework in the target computer take care of the execution. (To run a .net application, the target computer should

have .Net framework installed.) The .Net framework converts the calls to .net class libraries to the corresponding APIs of the Operating system. Whether you write code in C# or VB.Net, you are calling methods in the same .Net class libraries. The same .net framework executes the C# and VB.Net applications. So, there won't be any performance difference based on the language you write code. What is Visual Studio.Net ? Many people always get confused with Visual Studio .Net (VS.Net) and .Net technology. VS.Net is just an editor, provided by MicroSoft to help developers write .net programs easily . VS.Net editor automatically generates lot of code, allows developers to drag and drop controls to a form, provide short cuts to compile and build the application etc. VS.Net is not a required thing to do .net programming. You can simply use a notepad or any other simple editor to write your .net code!!! And you can compile your .net programs from the command prompt. Well, what I said is true theoretically.. but if you decide to use notepad for .net programming, by the time you develop few sample applications, MicroSoft would have introduced some other new technology and .net would be outdated. You may not want that. So, let us go by VS.net, just like every other .net guys. You can read more about VisualStudio.Net in the next article. .Net supported languages Currently .net supports the following languages: C# VB.Net C++ J# The above languages are from MicroSoft. Many third parties are writing compilers for other languages with .net support. Difference between VB and VB.Net Believe us, there is not much in common between VB and VB.net other than the name. VB.Net is a totally new programming language. It just retains the syntax of old VB. So, if you are a vb programmer, probably you may like VB.net than C# just because of the syntax. In addition to this, VB.net still support many of the old VB functions just for backward compatibility. But if you are a serious .net programmer, we strongly suggest never use old VB functions in VB.Net. So, switching from VB to VB.Net is just like learning a new programming language, with very small similarities between them. C# or VB.Net ? Which one to choose ? As we mentioned in earlier chapters, it makes no much difference. Whether you write code in VB.net or C#, when you compile, your code will get converted to MSIL (MicroSoft Intermediate language). It is this MSIL which you deliver to your customer in the form of a DLL or EXE. The MSIL is executed by the same .net

framework, whether you wrote it originally in C# or VB.net. The MSIL generated by C# and VB.net is almost 99% is the same! Many believe that C# has the power of C++ and VB.Net has the user friendliness of VB. That is not true. Both are equally powerfull and friendly. VB.net has backward compatibility with old Visual basic. So, it supports old vb functions. C# is a fresh, clean language. So strongly support using C# instead of VB.net just for this clean compiler. Many old VB guys usually like to stick with VB.net and are kind of scared of C#. We are sure that you will not take more than few days to get familiar with C# syntax. This online tutorial is based on C# and all samples will be provided in C#. Is it platform independant ? Many people ask this question "Java is platform independant, what about .net ?". The answer is "Yes" and "No" ! The code you write is platform independant, because whatever you write is getting compiled into MSIL. There is no native code, which depends on your operating system or CPU. But when you execute the MSIL, the .net framework in the target system will convert the MSIL into native platform code. So, if you run your .net exe in a WIndows machine, the .net framework for Windows will convert it into Windows native code and execute. If you run your .net application in Unix or Linux, the .net framework for Unix/Linux will convert your code into Unix/Linux native code and execute. So, your code is purely platform independant and runs anywhere! But wait, we said it wrong... there is no .net framework for Unix or Linux available now. MicroSoft has written the .net framework only for Windows. If you or some one else write a .net framework for other platforms in future, your code will run there too. So, let us wait until someone write .net framework for Linux before you run your .net code in Linux. Is it worth learning .Net ? Are you sure you have a very good job now and your job is safe for next 10 years? Then, probably you don't need to waste your time to learn this new technology. If you are not sure about the future of your job, better spend sometime and make sure you have fuel to run for next few years! How long it will take to learn .Net ? It all depends on how fast you can learn. If you are familiar with Visual Basic or C+ +, you can come to speed in .Net within 1-2 months. If you are a new to programming, we estimate 6 months will be a reasonable period to become comfortable with .Net world. Future of .Net MicroSoft is moving all its technologies to be .Net based or .Net related. The next version of SQL Server even supports writing stored procedures in .net

languages. .Net runtime will be part of all Operating Systems by default. In short, if you like to work on MicroSoft technologies for programming, .net would be the only choice you will have.

C# Language
Your first .NET program Here we will guide you through step by step process to create your first sample .NET application. All our sample code will be using C# syntax. Readers are suggested to stick to this new elegant language, than going back to your favorite VB style. Hello World Application using C# Let us get started the traditional way, with a 'Hello World' application. We hope you all have Visual Studio.NET installed on your computer. If you have VS.NET, goto the menu option File > New > Project. Select 'Visual C# projects' and choose the project template 'Console Application'. This will create a default A simple C# program would look like the following. using System; public class Hello { public static void Main (string[] args) { Console.WriteLine("Hello C# World"); } } When you create a new Console Application, it will create a default class and you can just insert one line of code into it: Console.WriteLine("Hello C# World"); Now compile and run your first program by pressing Ctrl + F5. You will see the following result : > Hello C# World You are done! You got your first C# program successfully running. If you do not have VS.NET, you may use any editor (including notepad) to create your first C# program. Create a new file with the name sample.cs and type the C# code shown. Now go to the command prompt and navigate to the folder where you have the .NET framework installed. Compile your csharp file by using the command 'csc': csc c:\samples\sample.cs csc is the C# compiler. The above command will produce the output file sample.exe. You can run the sample.exe and you will see the output from the program.

Analyzing your first program See the first line of code : using System; "System" is a namespace and the "using" directive says that all classes in the "System" namespace can be used in this class without using the fully qualified name. In our class, "Console" is a class in the namespace "System". To use this class you have to actually write : System.Console.WriteLine ("..."); But the using System; directive on top of the class allows us to use the class without including the namespace. So, you can now simply write : Console.WriteLine("..."); If you are familiar with Object Oriented Programming, you might not need more explanation for the next line - declaring a class. public static void Main (string[] args) - is the Main method, which is the starting point of the application. string[] args is the list of arguments that are passed to this application. (In our case, we are not passing any command line parameters). Console.WriteLine("...") is another line of important code. Console is a class, part of .NET class library included in System namespace. WriteLine is a method part if this class and used to print output to the default Console. -------------------------------------------------------------------------------------------------------------------C# Language Syntax and essentials This article will show you the basic statements in C# language and language syntax. Declaring Variables The following sample shows different ways you can declare a variable: int a; int salary, incomeTax, sum; int count = 10; string name; string fullName= "Little John"; Loop Statements while int i = 0; while ( i < 5 ) { Console.WriteLine ( i ); ++i; }

The above loop repeates 5 times and prints the value of i. The output of above code would be like this : 0 1 2 3 4

for int i = 0; for ( int i = 0; i < 5; i++ ) { Console.WriteLine ( i ); } The above loop repeates 5 times just like the while loop and prints the value of i. The output of above code would be like this : 0 1 2 3 4

do ... while int i = 0; do { Console.WriteLine ( i ); i++; } while ( i < 5 ); The above loop is pretty much same as the while loop. The only difference is, the condition is checked only after executing the code inside the loop. foreach string [] names = new string[] "Bill" }; foreach ( string name in names ) { Console.WriteLine ( name ); } { "Little John", "Pete", "Jim",

foreach loop can be used to iterate through a collection like array, ArrayList etc. The above code displays the following output: Little john Pete Jim Bill Conditional Operators if ... else This is the conditional operator, used to selectively execute portions of code, based on some conditions. string name = "Little John"; if ( name == "Jim" ) {

Console.WriteLine( "you are in 'if' block" ); } else { Console.WriteLine( "you are in 'else' block" ); } in the above case, it prints : you are in 'else' block Flow Control Statements break 'break' statement is used to break out of loops ('while', 'for', switch' etc). string [] names = new string[] { "Little John", "Pete", "Jim", "Bill" }; foreach ( string name in names ) { Console.WriteLine ( name ); if ( name == "Pete" ) break; } In the above sample, it iterates through the array of 4 items, but when it encounters the name "Pete", it exits the loop and will not continue in the loop anymore. The output of above sample would be : Little John Pete

continue 'continue' statement is also used to in the loops ('while', 'for' etc). When executed, 'continue' statement will move the exection to the next iteration in the loop, without continuing the lines of code after the 'continue' inside the loop. string [] names = new string[] { "Little John", "Pete", "Jim", "Bill" }; foreach ( string name in names ) { if ( name == "Pete" ) continue; Console.WriteLine ( name ); } In the above sample, when the value of name is "Pete", it executes the 'continue' which will change the execution to the next iteration, without executing the lines below it. So, it will not print the name, if the name is "Pete". The output of above sample would be : Little John Jim Bill

switch ifyou have to writeseveral if...else conditions in your code, switch statement is a better way of doing it. The following sample is self explanatory: int i = 3;

switch ( i ) { case 5: Console.WriteLine( "Value of i is : " + 5 ); break; case 6: Console.WriteLine( "Value of i is : " + 6 ); break; case 3: Console.WriteLine( "Value of i is : " + 3 ); break; case 4: Console.WriteLine( "Value of i is : " + 4 ); break; default: Console.WriteLine( "Value of i is : " + i ); break; } In the above sample, depending on the value of the conditional item, it executes appripriate case. In our code, since the value of i is 3, it executes the third case. The output will be as shown below: Value of i is : 3

DataTypes in C# Datatypes in C# and .NET DataTypes are the basic building blcok of any language. Microsoft has tried to standardize the datatypes in .NET framework by introducing a limited, fixed set of types that can be used to represent almost anything in programming world. C++ was very rich in datatypes, but that leads to confusion too. Especially, when you write components that may be consumed by applications written in other platforms, you have to make sure the types used are compatible with other platforms too! .NET types start from a clean slate. All .NET languages share the same types. So, they are all compatible and no worries. This means, you can call C# code from VB.NET and vice versa, without worrying about type conversions. .NET data types are either structures or classes, part of the System namespace. For example, the following data types are implemented as struct in .NET: Int16 Int32 Double (String is implemented as a class in .NET, for various reasons.) If you are not very familiar with struct and class, don't worry about it. You can just use them as if they are simple data types. Here is how you can declare variables of type Int, Double and String: Int16 age, employeeNumber; Double salary; String name, address; You can use any of the .NET data types directly in any .NET language - in C#, VB.NET or xyz.NET. But in addition to the .NET types, each language provides a set of primitive types, which map to the

corresponding types in .NET class library. This is why you may see some people use string and some others use String. There is no big difference. string is a primitive data type in C# and String is the corresponding class in .NET class library. The string in C# is mapped to the class in .NET class library. So, whether you use string or String, there is no real difference. DataTypes in C# and the corresponding class/struct in .NET class library The following list shows the list of data types available in C# and their corresponding class/struct in .NET class library. C# Data type sbyte byte char float decimal double ushort short uint int ulong long bool string object Mapped to .NET class/struct System.SByte System.Byte System.Char System.Single System.Decimal System.Double System.UInt16 System.Int16 System.UInt32 System.Int32 System.UInt64 System.Int64 System.Boolean System.String System.Object

Value Types & Reference Types In C# data types are classified into two : value types reference types The following tables shows some of the differences between values types and reference types. value types allocated on stack a value type variable contains the data itself when you copy a value type variable to another one, the actual data is copied and each variable can be reference types allocated on heap reference type variable contains the address of memory location where data is actually stored. when copying a reference type variable to another variable, only the memory address is copied. Both variables will still point to the same memory

independantly manipulated. integer, float, boolean, double etc are value types. struct is value type.

location, which means, if you change one variable, the value will be changed for the other variable too. string and object are reference types. classes and interfaces are reference type

This chapter from another Book

1
Getting Started
C# is pronounced as "C sharp". It is a new programming language that enables programmers in quickly building solutions for the Microsoft .NET platform. Today, one cannot, just cannot, afford to ignore C#. It is our considered opinion that it holds immense promise and we are going to try our best, through this book, to help you realize its potential. Be assured, we are not going to teach you just another programming language. It is our intention to help you apply C# in practical situations, to actually implement your newly acquired knowledge on the Net. With this brief introduction, let us embark on a path that will take you to new adventures in the world of Internet. In this chapter, we will get you started with C# by introducing a few very simple programs. For remember, even a journey of a thousand miles must begin with a single step. We assume that you have no prior knowledge of any programming language. But before we get ensnared in the fascinating world of C#, let's make a directory where we will save all our work. In order to do so, click on Start, Programs, then go to Accessories and select Command Prompt (Windows 2000) or the MS-DOS Prompt as it is called in Windows 98. Once you are at the command prompt create a directory called csharp (md csharp) and change to this directory (cd csharp). Now type the command 'edit a.cs', which will open the MS-DOS editor - the world's simplest editor.
C:\csharp>edit a.cs

Yes, we very well understand how you must be yearning to write your first C# program and get it working. But before we do that, there are certain intricacies that you must understand. What a.cs refers to is called the filename or program name. Here we have named our file or program a.cs. Why a.cs? Well, before we began writing this book, we consulted a renowned astrologer who predicted that if we named our first file a.cs then great luck would be showered on us. Not wanting to quarrel with the stars, we named our file a.cs. But you are free to go ahead and call your file any name you want. But then do so at your own risk! Remember, forewarned is forearmed! Jokes aside, 'cs' is the extension used for C# files. They say of all the things you wear, your expression is the most important. Notwithstanding this, one does look more dapper in a suit rather than a vapid shirt and trousers. Similarly, though it is not mandatory to provide the extension 'cs', you can make a filename seem more impressive by giving it an extension. To reiterate, you could have given the extension say

'ws' too; it does not matter. But absent minded as we are, it is more prudent to give appropriate extensions while naming files. As the first step, we will understand the basic structure of a C# program.
a.cs class zzz { }

Here we start with the word class zzz followed by open and close curly braces. A class is nothing but a collection --- a collection of everything that the programming language contains. It is like a packet or a container, which can hold anything. Hence everything in a C# program must be enclosed within a class. We have named our class zzz, again you could have named it anything else but if you would rather follow our naming convention (for reasons well amplified above!), name it zzz. Now for the part that you've been eagerly waiting for! In order to execute the program, go to the File menu, and click on Exit. You will get a dialog box asking you whether you want to save the file or not, say yes. Now that we have typed and saved our file we need to execute it. The compiler creates executable code. The command used to call the C# compiler is csc followed by the program name. Since our program name is a.cs, the command csc a.cs will call the compiler. A compiler is a program which understands the C# programming language. Thus the word class is part and parcel of the C# language. Microsoft lets you freely download the C# compiler from their web site : http://msdn.microsoft.com/library/default.asp. Select .Net Framework SDK under .NET Development. Choose the Download option to download the sdk which is around 127 MB large. Install the product on your machine cause if you dont, none of the following programs will work. Also, Internet Explorer 5.5 and Microsoft Data Access Components(2.7) must be installed prior to installing the sdk Once done, type the command as follows:
C:\csharp>csc a.cs

You will see the following output on your screen in the dos box.
Microsoft (R) Visual C# Compiler Version 7.00.9254 [CLR version v1.0.2914] Copyright (C) Microsoft Corp 2000-2001. All rights reserved. error CS5001: Program a.exe does not have an entry point defined

Just as the excitement was beginning to grow, our program returns with an error message. Don't worry, occasional failure is the price of improvement. The error message starts with an error number CS5001 followed by a cryptic message, which we do not understand. We are aware of the fact that everything has a beginning and an end. Similarly, a C# program also has a start and an end. Ah! Now you realize why the error occurred. We forgot to tell C# where to start executing our program from. This starting point is also called an entry point. You can specify the entry point by adding static void Main() to your program, just as we have done below.
a.cs class zzz {

static void Main() { } }

Compile the above code giving the command as csc a.cs. Voila! Now no errors. The compiler will now generate an exe file called a.exe. Giving the command dir at the command prompt will prove the same. On keen observation you will notice that among the 2 files listed, there is a file by the name a.exe. Simply type 'a' at the command prompt, your program will now be executed!
C:\csharp>a

The program will run but shows no output on our screen. But, at least we get no errors. The words, static and void, will be explained to you a little later, in the right perspective. Thus if you had felt the beginnings of a massive headache, you can breathe easy! Anything followed by '(' and ')' brackets is called a function. So, it is obvious that Main is nothing but a function. Here we are creating a function called Main. It is followed by the '{' and '}' curly braces. Note that the letter M in Main is capital. Thus C# requires a function called Main, which is the first function that will be executed. Failure to do so will result in an error. Ergo, whenever you see a word beginning with an open '(' and close bracket ')', C# and most other programming languages call it a function. The { signifies the start of a function and the } signifies the end of the function. The guys who designed the language decided to use {} braces instead of start and end. When you tell people that you are learning a programming language, you are actually learning to use {} braces to specify the beginning and end of a function. These rules have to be remembered by rote. You have no choice. Now we are ready to add some code in our program. In order to do so, add the line WriteLine("Hell"), just as we have done below.
a.cs class zzz { static void Main() { WriteLine("Hell") } }

Oops! The astrologer had promised showers of luck! Even a drizzle seems far away! Executing the above program results in the following error:
Compiler Error a.cs(5,18): error CS1002: ; expected

The error message begins with the file name, a.cs followed by round brackets containing the line number and the column number, where the error occurred. The compiler informs us that it found an error on line number 5 and column number 18 and it expects a ;. As the clich goes, when the going gets tough, the tough get going. So we shouldn't lose heart as yet; let's understand why this error occurred. Look at WriteLine within the brackets; doesn't it ring a bell? Isn't WriteLine a function too? But here we do not have the curly braces following it. This is because here we are not creating a function like we created Main. Then what is it that we are doing? We are calling a function called WriteLine, which has already been created.

The error says ';' expected. Though it is obvious to us that the statement has ended, unfortunately for you and me, C# isn't so smart. It requires a semi-colon to tell it loud and clear that the statement has ended. Merely pressing enter does not suffice. Though not so for other programming languages, in C# it is mandatory to use a semi-colon. Alas! Each programming language has its own rules! At this juncture, an intelligent question would be - But why semi-colon? Why not any other punctuation mark? We don't know for sure but perhaps the developers of C# were asked to select a character that would indicate the end of a statement. The non-compromising species that we are, they could not arrive at a consensus. Result? Grandma's recipe of eene meene mina mo! When they stopped, their finger was pointing at the semi-colon, hence they selected the same. Thus rules are rules; as preposterous as they may sound, they must be followed. Add the semi-colon and execute the program. Also languages like ABAP/4 from SAP ends lines with a dot (full stop). Thus we expect to understand programming in English. Every language expects an end of statement/command terminator. Every language expects a symbol to denote when the user has finished saying something. In C# it is a ; , other languages have their own symbols. Remember that the statement or function WriteLine was written on line number 5 hence the error reported line number 5.
a.cs class zzz { static void Main() { WriteLine("Hell"); } } Compiler Error a.cs(5,1): error CS0103: The name 'WriteLine' does not exist in the class or namespace 'zzz'

Another error! We are extremely disappointed, it just doesn't seem our day. However we firmly believe that you may be disappointed if you fail, but are surely doomed if you don't try. And we don't want to be doomed do we? So let's keep our chin up and carry on. But you know what's most irritatingly bothersome? Why are all error messages so difficult to understand? Well, with the experience that we have gained over the years we have learnt that if error messages could be understood then we wouldn't get them in the first place! In any case, to be truly candid, the error occurred because we pulled a fast one on you! We are calling a function WriteLine but in fact no such function exists. The accurate name of the function is not WriteLine but System.Console.WriteLine. Microsoft is known to fancy big names and here is one more example. In any case, let's execute the program.
a.cs class zzz { static void Main() { System.Console.WriteLine("Hell"); } } Output Hell

Finally, no errors! Surely you feel blessed! It displays the word 'Hell', and we suspect that's exactly what you are going through right now. But if you follow our programs step by step we assure you that heaven is not too far away. Now remove all the extra spaces and 'enters' from your program, just as we have done below and compile the program again.
a.cs class zzz {static void Main() {System.Console.WriteLine("Hell");}} Output Hell

You will notice that doing so does not give any errors. Just like the previous program, it displays 'Hell'. The C# compiler is not affected by it. But using spaces and 'enters' definitely make your program neater and thereby more readable. The effect is especially appreciated in large programs and more so when someone else has to go through them. Having said that, anyway, the first thing that C# compiler does is removes all the spaces and enters from the program code you have written. In the next program, we have called WriteLine function twice.
a.cs class zzz { static void Main() { System.Console.WriteLine("Hell"); System.Console.WriteLine("Bye"); } } Output Hell Bye

On executing this program, 'Hell' and 'Bye' are displayed on two separate lines. Here, we are not required to give anything that has the 'enter' effect, WriteLine automatically prints on a new line each time. Which simply means you can call a function as many times as you like. In the next illustration, let's understand how functions are called and created. Here we are calling a function abc().
a.cs class zzz { static void Main() { abc(); } } Compiler Error a.cs(5,1): error CS0103: The name 'abc' does not exist in the class or namespace 'zzz'

On executing this program you will get, what else, but an error. Peter Drucker, the famed management guru had once said that the better a man is, the more mistakes he will make, for the more new things he will try. So there you go - next time you encounter an error, simply tell yourself that you have just become better at whatever you are doing.

In any case, the error says that abc does not exist. Here we are calling a function called abc(), but where is abc() defined or created ? It is not a function that has been provided by C# to us free of charge. It is our own homegrown function that we are calling. The lesson here is that we cannot call a function without first creating it. So, to rectify this error we will first create a function abc. Our next example demonstrates this.
a.cs class zzz { static void Main() { abc(); } static void abc() { System.Console.WriteLine ("Hell"); } } Output Hell

In the function abc, we have included only one statement- WriteLine within the curly braces. The '{' and '}' braces indicate the beginning and the end of this function. Alternatively, a function can contain millions of lines of code that will be executed when the function is called. Since everything is contained in a class, our function abc is also created within the class zzz but outside Main. But the function is called from Main. On executing the program, 'Hell' is displayed. This is because we have included the code for 'Hell' to be displayed in the function abc. Thus, when the control reaches the line abc(); it searches for that function and executes the code within that function. We will explain static and void later as promised. You can call as many functions as you like from your program. But you must remember to separate each one with a semi-colon. The next program illustrates this.
a.cs class zzz { static void Main() { abc(); pqr(); abc(); } static void abc() { System.Console.WriteLine ("I am ABC"); } static void pqr() { System.Console.WriteLine ("I am PQR "); } } Output I am ABC I am PQR I am ABC

At first the function abc is called, then pqr and then again we are calling abc. On executing this program 'I am ABC', 'I am PQR' and 'I am ABC' will be displayed. This is because we have included the code for these lines to be displayed in the respective functions. In the following program we are calling the function pqr from abc and not from Main.
a.cs class zzz { static void Main() { abc(); } static void abc() { pqr(); System.Console.WriteLine ("I am ABC"); } static void pqr() { System.Console.WriteLine ("I am PQR "); } } Output I am PQR I am ABC

In the function abc, we are first calling pqr and then displaying 'I am ABC' using the WriteLine function. Hence, first 'I am PQR' is displayed and then 'I am ABC'. Thus, this program demonstrates how functions can be called from other functions. Now that we have created our own functions abc and pqr, we have an intuitive understanding of how C# created the function System.Console.WriteLine. The next program uses the printing or formatting capabilities of the WriteLine function.
a.cs class zzz { static void Main() { System.Console.WriteLine("100 {0}",100); } } Output 100 100

The zero in the curly braces means that after the first comma there is some value and that it should display this value. You cannot differentiate between the two 100's. The {0} is replaced with 100, the number, which follows the first comma. If you don't like the number 100, use the number 420 instead. We won't mind - at least it's something that some of you can easily identify with! The program below is simply an extension of the above.
a.cs class zzz { static void Main()

{ System.Console.WriteLine("100 {0},{1}",100,200); } } Output 100 100,200

Here the {0} is replaced with 100 and {1} is replaced with 200. The comma (,) separates the two numbers. Thus {0} means the first number and {1} means the second. C# likes to count from zero and not one.
a.cs class zzz { static void Main() { ii; ii=20; System.Console.WriteLine ("{0}",ii); } } Compiler Error a.cs(5,1): error CS0201: Only assignment, call, increment, decrement, and new expressions can be used as a statement a.cs(5,1): error CS0103: The name 'ii' does not exist in the class or namespace 'zzz' a.cs(6,1): error CS0103: The name 'ii' does not exist in the class or namespace 'zzz' a.cs(7,33): error CS0103: The name 'ii' does not exist in the class or namespace 'zzz'

Experience is knowing a lot more of things you shouldn't. But now that you have decided to embark upon this book, let's see what you should know!! Executing this program results in a large number of errors as shown above. Let's understand the rationale behind it. Here we have included a strange word --- ii. This word ii is being given a value of 20 as ii=20. But C# is a shy program. It does not speak to strangers! Here ii is nothing but a stranger to C#. C# does not know who or what ii is. You can't just write words that you feel good about. So, in order to rectify this error we must tell C# who ii is. Our next program will demonstrate how this can be done.
a.cs class zzz { static void Main() { int ii; ii=20; System.Console.WriteLine ("{0}",ii); } } Output 20

Note that in this program we have added the word int before ii. The word int indicates that ii is an integer or a number. Each time we create our own word like ii, C# wants to know what we will store in this word. We will understand this better and in totality in just a little while. Here we are initializing ii to 20 or giving it a value of 20 by writing ii = 20. Why 20? Maybe because we are feeling very youthful today! Following this we have the WriteLine function. Now, it is a known fact that jaggery is a good substitute for sugar. Similarly, in C# you can substitute a number with a word. So, in WriteLine we have

used the word ii instead of a number. The word ii gets replaced with the value 20. So, on executing the program, the number 20 is displayed. You may be wondering as to why should you ever use a word when you can use a number directly. Our next program will enlighten you on this.
a.cs class zzz { static void Main() { int ii; ii=20; System.Console.WriteLine ii=30; System.Console.WriteLine ii=ii+10; System.Console.WriteLine ii=ii+1; System.Console.WriteLine ii++; System.Console.WriteLine } } Output 20 30 40 41 42

("{0}",ii); ("{0}",ii); ("{0}",ii); ("{0}",ii); ("{0}",ii);

The first three lines of this program are identical to those of our previous one. Thus in the first, the WriteLine function will display the number 20. Thereafter, by saying ii=30 we are initializing the word ii to a value 30. In effect, we are changing the value of ii from 20 to 30. So, WriteLine will now display 30. For conceptual understanding, we earlier introduced ii as a word. However, in the software world, it has another name; it is actually called a variable. Thus, a variable is a word whose value varies or changes. ii initially had a value 20 that changed to 30. Coming back to what the word int means- when you say int, int means integer or number. When we say int ii, it means that the variable ii will store a number. ii could also be used to store the letters of the alphabet like the names of people. It could also store a date. But here we wanted ii to store a number. So, we have to tell C# in advance as to what the variable is going to store. Hence we say int ii. C# understands the word int as int is a part of the C# programming language. The variable ii started with the value 20 and is now holding a value 30. In the next line we have ii=ii+10. The 'equal to' sign makes this statement look complicated. To avoid confusion, always start by looking to the right of the 'equal to' sign. To the right of the equal to sign we have ii+10. Since ii is holding the value 30, ii+10 is read as 30+10, which evaluates to 40. Hence ii=ii+10 will now be read as ii=40. This value 40 is given to the variable on the left-hand side. Now that ii has a value 40, WriteLine will display 40. Similarly, we say ii=ii+1. Here the value of ii is incremented by one. And the new value of ii, which is 41 will be displayed by WriteLine. In the next line we have ii++. Note that ii=ii+1 and ii++ do the same thing. They both increment the value of ii by 1. Hence WriteLine will now print the number 42. This is a big problem with programming languages. As there are many ways to skin a cat, there are also many ways to increase the value of a variable. So ii = ii + 1 and ii++ do the same thing.

A programmer thus has the choice to use either of the two ways to do the same thing. There you go ---as you can see, first time programmers have unfortunately a lot to learn. In daily life, a hundred different people can do the same chore in a hundred different ways. Similarly, in programming there is more than one way of doing a particular thing. Programming becomes a problem because of redundancy. Since there are two ways of doing the same thing you have to learn them both and that can be very confusing. Of course, it is at your discretion to choose the method you are comfortable with. Henceforth, even though there may be many other ways of doing a particular thing, we will teach you only one method that we find appropriate. A variable is a word that stores a value. This value can be changed at will by the programmer. Wherever we can use a number, we can also use a variable. The next program may seem alien to you. This is because it speaks the truth. If it finds that a condition is true it outputs true and if it finds the condition to be false it outputs false. Very unlike some of you, who would do just the opposite!
a.cs class zzz { static void Main() { System.Console.WriteLine System.Console.WriteLine System.Console.WriteLine System.Console.WriteLine System.Console.WriteLine System.Console.WriteLine } } Output True False False True False True

("{0}", ("{0}", ("{0}", ("{0}", ("{0}", ("{0}",

5 5 2 2 2 2

> 2); < 2); < 2); <= 2); != 2); !=3);

Let's understand this program line by line as usual. Here the first line says WriteLine("{0}", 5 > 2); Is 5 > 2 ? Yes. So the condition 5 > 2 evaluates to true. Hence the {0} in WriteLine is replaced with True and the WriteLine function displays True. 5 > 2 is called a condition. A condition is like a question which has to result in a yes or no or a true or false. In this case the number 5 is greater than the number 2 and hence the function evaluates to true. C# understands the words true and false. In the second WriteLine we have the condition 5 < 2. Is 5 < 2? No. So the condition 5 < 2 evaluates to false and hence WriteLine displays False. Similarly, the next condition 2 < 2 is not true and hence False is displayed. In the next statement we have 2 <= 2. Here the first sign being '<' it is first checked whether 2 < 2? No, 2 is not less than 2. So then the second sign '=' is checked i.e., whether 2 = 2? Yes. So the condition 2 <= 2 evaluates to true and WriteLine displays True. <= is thus two conditions in one .

In the next WriteLine we have the condition 2 != 2. '!=' means 'not equal to'. But 2 is equal to 2, hence the condition evaluates to false and False is displayed. The comparison is false, therefore the condition is false. In the last statement we have the condition 2 != 3. Is 2 != 3? Yes 2 is not equal to 3, so the condition evaluates to true and True is displayed. This True and False is a special data type in C#. It is called 'Bool' or boolean derived from Boolean algebra.
a.cs class zzz { static void Main() { bool ii; ii=true; System.Console.WriteLine ("{0}", ii); ii=false; System.Console.WriteLine ("{0}", ii); } } Output True False

In our previous programs we used the data type int for the variable ii. This meant that ii could store integers or numbers. Similarly, you can now initialize ii to either true or false. This is possible by using the data type bool for ii. A data type means the type of data a variable can hold. Therefore, here we are saying bool ii. In the first case we are initializing ii to true. So in WriteLine, {0} is replaced with true. In the second case ii is initialized to false and {0} is replaced with false. In a gist, we now know that variables can be either bool or logical or they can contain the words True or False. Also, variables can also contain numbers. Let's see how C# distinguishes between data types.
a.cs class zzz { static void Main() { bool ii; int jj; ii=10; jj=false; } }

Executing the above program gives the following errors:


Compiler Error a.cs(6,4): error CS0031: Constant value '10' cannot be converted to a 'bool' a.cs(7,4): error CS0029: Cannot implicitly convert type 'bool' to 'int'

If you want the rainbow, you gotta put up with some rain. So lets understand the reason behind the errors. Here C# is internally saying that it distinguishes between data types. In that sense C# is very petty about what values you give to variables. Bool can't mix with int and vice versa. Since ii is a bool you can't initialize it to 10, which is a number. C# is very strict about this. And because jj is an int you can't initialize it to false. So you have to be very careful about how you initialize your variables. After all it doesn't make sense to ask someone who is good at driving to teach computers and vice versa.

Everyone has his or her place in life. Similarly, variables also have their place. Hence a variable declared as a bool can only have values true or false. Similarly, int can have only numbers or integers, it cannot take true or false values. Our next program is similar to one of the previous programs.
a.cs class zzz { static void Main() { bool ii; ii=6 < 7; System.Console.WriteLine ("{0}", ii); } } Output True

Here ii is a variable of type bool. In the next statement we have ii = 6 < 7. As you already know, in such a case you should start by looking to the right of the 'equal to sign'. Because 6 is less than 7 the condition evaluates to true and ii will be initialized to true. Hence {0} is replaced with the value of ii, which is true and True is displayed. C# is called a strongly typed language because you cannot initialize a variable of type int to a variable of type bool. The reason C# is very strict about this is because this system eliminates a large number of sloppy programming errors. Some languages like C on which C# is based on do not care what values you initialize your variables to. C# is stricter than even Java. In some ways, it's like your mother when it comes to telling you what you are doing wrong in life. Thus it is extremely difficult to make dumb errors in C#. Remember when you are writing code in C#, the compiler is always peering down your shoulder making sure you do not get away with any errors.

If Statement
So far the code that we have written is rather useless. This is because it always gets executed. Life is enjoyable only because it is unpredictable. We don't know what tomorrow is going to bring. Variety is the spice of life! Similarly, we would like to write computer programs, which add spice to programming. We want to write programs that behave differently depending upon different situations or circumstances. And this can be achieved with the help of the if statement. So fasten your seatbelts and get set to ride! The next few programs will demonstrate the usefulness and application of the if statement.
a.cs class zzz { static void Main() { if ( false ) System.Console.WriteLine ("Hi"); } } Compiler Warning a.cs(6,1): warning CS0162: Unreachable code detected

In this program we have included the word 'if' followed by false in round brackets. This is the if statement and its syntax. Syntax is the grammar in writing. Thus we have no choice but to abide by the rules. It is called a statement because anything that C# recognizes is called a statement. When you run this program, you realize that there is no output. So this program will simply display nothing. Now you know why we get the above warning as our code will never get executed. Let's understand the rationale behind it. The if statement lets you include decision making in your program. It decides whether to execute the next line or not. When the if statement evaluates to false then the next line is ignored. The if statement brings with it the power to decide whether certain code should be executed or not. The following program will make this concept clearer.
a.cs class zzz { static void Main() { if ( false ) System.Console.WriteLine ("Hi"); System.Console.WriteLine ("Bye"); } } Output Bye

The if statement looks at the immediate next line, it doesn't look at the line after that. Since the if statement influences only one line, you will see only Bye displayed and not Hi. Same warning again. But if you want both the statements to be affected by the if then enclose them within curly braces. This is illustrated below.
a.cs class zzz { static void Main() { if ( false ) { System.Console.WriteLine ("Hi"); System.Console.WriteLine ("Bye"); } } }

Here we have included both the lines of code within the braces. Now the if statement will affect both the lines of code. The condition being false, nothing is displayed. Thus, the if statement gives us the option to execute or not to execute a certain piece of code. If we always use false then the code will never be called. But what did we tell you about conditions? They return either true or false. So, in the next program we have 3 > 8 as the condition. Since 3 is not greater than 8 the condition evaluates to false. Since there are no curly braces, only the next line is affected by the if statement. Hence only Bye is displayed.
a.cs class zzz {

static void Main() { if ( 3 > 8 ) System.Console.WriteLine ("Hi"); System.Console.WriteLine ("Bye"); } } Output Bye

Let's look at another variation of this program. Now, the interesting part is that wherever you can use a condition you can also use a variable which is of type bool, which we know evaluates to either true or false.
a.cs class zzz { static void Main() { bool ii; ii=true; if ( ii ) { System.Console.WriteLine ("Hi"); System.Console.WriteLine ("Bye"); } } } Output Hi Bye

Here the variable ii is declared as a bool and then initialized to true. In the next line we have if (ii). The variable ii holds the value true and hence the if condition evaluates to true. The condition being true both Hi and Bye are displayed. Note that here both the statements are included in the curly braces resulting in both the statements being affected by the if statement. Thus the if statement is affecting a block of statements. Declaration is another way of saying that we are creating a variable. In the following program we have an if with the else. If the if condition evaluates to true then the statement following it is called but if it evaluates to false then the else is called.
a.cs class zzz { static void Main() { if ( false ) System.Console.WriteLine ("Hi"); else System.Console.WriteLine ("Bye"); } } Output Bye

Here, since the condition evaluates to false the else is called and hence Bye is displayed. Thus the additional else statement specifies a statement that is executed when the condition is false. This construction covers all possibilities, as a condition can be either true or false. In an 'if-else' construct one of them have to be executed. Computer programs are said to be made intelligent because of the if statement. The more the use of the if statement, the more intelligent your program becomes. The if statement is one of the main building blocks of any programming language. Thus all programming languages have to have a if statement.

Loops
The if statement is the cornerstone of programming because it lends intelligence and a decision making power to the language. The second important constituent of any programming language is a looping construct. In a program many times you would need to repeat instructions. In C#, the for statement is one form of a loop that lets you repeat statements. However, as we already know, a statement can also be a block of statements, thus it also allows repetition of multiple statements. Our next program explains the for loop.
a.cs class zzz { static void Main() { int ii; for ( ii = 1; ii <= 5; ii++) System.Console.WriteLine ("Hi {0}", ii); } } Output Hi 1 Hi 2 Hi 3 Hi 4 Hi 5

The for has 2 semicolons as part of its syntax or rules. The statement up to the first semicolon is executed only once. For the first time and only the first time ii is initialized to 1. Remember up to the first semicolon the statement is executed only once. The statement enclosed within the first and second semicolon is a condition. The condition checks whether ii <= 5 evaluates to true. Since this condition evaluates to true, the statement within the open and the close braces gets executed. If the condition evaluates to false, the statement is ignored and the loop terminates. The variable ii has a value 1 which is less than 5, so System.Console.WriteLine will be called which displays 'Hi 1' as the value of ii is 1. After the statement gets executed, the last part of the for i.e. from the second semicolon to the closing bracket gets executed. ii++ will increase the value of ii by 1, making it 2. The condition is checked again, is 2 <= 5. The answer here is true, so 'Hi 2' is displayed. And this roller coaster goes on till the condition is false. When ii has the value 6, the condition checked is, is 6 <= 5. The answer being false, the for terminates. This is how the for statement enables the repetition of code. Our next example will further help to illustrate this.
a.cs class zzz { static void Main() { int ii;

for ( ii = 1; ii <= 5; ii++) System.Console.WriteLine ("Hi {0}", ii); System.Console.WriteLine ("Hi {0}..", ii); } } Output Hi 1 Hi 2 Hi 3 Hi 4 Hi 5 Hi 6..

In this program we have two WriteLine statements. The for loop follows the same rules as the if statement. Thus in absence of curly braces the for loop will affect only the immediate next statement. Therefore, the for loop will print numbers from 1 to 5 along with hi. The moment the for loop terminates, ii with the dots will print Hi 6... This goes to prove that when ii has a value six, the for loop will terminate. The following program demonstrates how the for loop enables repetition of multiple statements.
a.cs class zzz { static void Main() { int ii; for ( ii = 1; ii <= 5; ii++) { System.Console.WriteLine ("Hi {0}", ii); System.Console.WriteLine ("Hi {0}..", ii); }}} Output Hi 1 Hi 1.. Hi 2 Hi 2.. Hi 3 Hi 3.. Hi 4 Hi 4.. Hi 5 Hi 5..

Here, both the WriteLine statements are enclosed within curly braces. Therefore, both the statements are affected by the for loop. Hence, in this case, each number is displayed twice along with Hi, once without the dot and once with the two dots. Similar to the for loop is the while loop.
a.cs class zzz { static void Main() { int ii; ii=1; while ( ii <= 5 )

{ System.Console.WriteLine ("Hi {0}", ii); } } }

The while loop takes a condition, hence the variable ii is initialized to 1 before entering the loop. The condition checks whether ii <= 5 evaluates to true. Currently the value of ii is 1. The condition evaluates to true and the statement within the curly braces is executed. System.Console.WriteLine is called with Hi and the value of ii. Note that here we are not changing the value of ii within the loop. Since the value of ii remains 1 the condition always evaluates to true and the loop will go on forever, indefinitely. We can't have anything go on forever, can we? There has to be a stop to it somewhere! Our next program will resolve this problem.
a.cs class zzz { static void Main() { int ii; ii=1; while ( ii <= 5 ){ System.Console.WriteLine ("Hi {0}", ii); ii++; } } } Output Hi 1 Hi 2 Hi 3 Hi 4 Hi 5

This program is similar to the previous one. The only change that we have made is that we added the line ii++; thus for the first time Hi 1 is displayed. Then the moment ii++ is encountered the value of ii is incremented by 1, making it 2. Then the condition, 2 <= 5, is checked. The condition being true, once again we enter the loop and Hi 2 is displayed. This will go on until ii becomes 6. Once ii is 6 the condition evaluates to false and the loop terminates. Your mind may ponder over the question, "Should I use a for or a while?' The for loop is similar to the while loop. To answer your question in the most simple manner "On Mondays, Wednesdays, Fridays use for and on Tuesdays, Thursdays, Saturdays use while. Sundays we assume no one writes code". Alternatively "Toss a coin, heads use while, tails don't use for" ;-) In other words, it is at your discretion to use the one you are comfortable with. Once again C# offers you multiple ways of doing the same thing.

The Return statement


Let's understand the return statement with our next example.
a.cs class zzz { static void Main()

{ int ii; ii = abc(); System.Console.WriteLine("hi {0}",ii); } static int abc() { System.Console.WriteLine("abc"); return 100; } } Output abc hi 100

In this program, at first, ii is declared as a variable of type int. Then we start executing the line ii=abc(); Doesn't the right hand side of the statement ring a bell? Aren't we calling the function abc() ? Hence at this point the control passes to the function abc(). In the function we have the WriteLine statement, which prints 'abc'. Thereafter, we have a return statement. It says return 100. In effect, the function abc() is returning a value 100. Thus the statement ii = abc(); will now be read as ii=100. Now that ii has a value 100, {0} in WriteLine is replaced with 100 and in turn 100 is displayed.
a.cs class zzz { static void Main() { int ii; ii = abc(); System.Console.WriteLine("hi {0}",ii); } static void abc() { System.Console.WriteLine("abc"); return 100; } } Compiler Error a.cs(6,6): error CS0029: Cannot implicitly convert type 'void' to 'int' a.cs(12,1): error CS0127: Since 'zzz.abc()' returns void, a return keyword must not be followed by an object expression

Executing the above program results in errors. Here we have static void abc(). What static means, we will explain a little later. It is with the intention to enable you to learn better, so please bear with us. The word void means nothing. So by saying void abc() we are saying that the function abc() does not return any value. Functions may/maynot return values. Earlier abc returned an int. When a function returns void as in this case, we are saying that abc cannot return a value. But in the function code we have written return 100. Therefore, because of this contradiction we get the error. Note that in the previous program we did not get an error. This was because we had said static int abc(). Here int signifies the return type of the function. Since the function returns a number we used int. In our next example we have made only one System.Console.WriteLine("Finish"); after the return statement. addition i.e. we have added

a.cs class zzz { static void Main() { int ii; ii = abc(); System.Console.WriteLine("hi {0}",ii); } static int abc() { System.Console.WriteLine("abc"); return 100; System.Console.WriteLine("Finish"); } } Compiler Warning a.cs(13,1): warning CS0162: Unreachable code detected Output abc hi 100

On executing this program, you will find that the output is the same as the previous program. To your amazement you do not see the word 'Finish' displayed. No, it is not because C# doesn't like you. The reason is that anything after the return statement is ignored. Thus, you may have a hundred WriteLine statements after the return statement but they will all be ignored. Simply stated, no lines after return statement will get called. That is why the C# compiler, courteous as it is, gives you a warning and not an error.

More on data types.......


You have already learnt about two data types, int and bool. Our next program introduces a new data type 'string'.
a.cs class zzz { static void Main() { string s; s= "hell"; System.Console.WriteLine(s); } } Output hell

In this program, the variable s is declared as a string. This implies that s will store mainly letters of the alphabet. Then s is initialized to hell, which is nothing but a collection of the letters of the alphabet. Note that all strings have to be enclosed within double inverted commas. System.Console.WriteLine displays the value of the variable s, which is 'hell'. Earlier we wrote a string in double inverted commas directly. However, this time we are using a variable name instead.

Now we know the first parameter to the WriteLine function is a string. We earlier named our variable ii and now we have called it s. Actually, we name our variables depending upon the time we write our programs. You decide your own rules for naming variables. Anything you enclose in double quotes is called a string. System.Console.WriteLine is smart enough to display strings, bools and int. Let's look at another variation of the above program.
a.cs class zzz { static void Main() { string s; s= "hell"; System.Console.WriteLine( "{0}", s); } } Output hell

This program is exactly like the previous one, the only difference being that we have used {0} instead of writing only s. Here the {0} is replaced with the value of s, which is 'hell'. Thus, using the {0} is preferable as it understands a large number of data types and how to display their values. Consolidating, our next example incorporates all the data types that we have learnt so far.
a.cs class zzz { static void Main() { string s; int ii; bool jj; ii=10; jj=false; s="hell"; System.Console.WriteLine("{0} {1} {2}", ii, jj, s); } } Output 10 False hell

Here the variable s is declared as a string. Then ii is declared as int and jj is declared as bool. In the next three statements we are initializing each of the variables. ii is initialized to 10, jj is initialized to false and s is initialized to hell. Now, with the help of a single WriteLine statement we are displaying the values of all the variables. {0} is replaced with 10, {1} is replaced with False and {2} is replaced with hell. This goes to prove that all the data types can be displayed together, in a single WriteLine statement. Thus, C# allows all the data types to co-exist in harmony. Now only if the people of our country could do the same!

Passing parameters to functions


By now you are familiar with functions and how functions are called. The next program illustrates how parameters are passed to functions.

a.cs class zzz { static void Main() { abc(10,false,"hell"); } static void abc(int i, bool j, string s) { System.Console.WriteLine("{0} {1} {2}", i,j,s); } } Output 10 False hell

We have again used the System.Console.WriteLine function to display values of variables or merely display text onto the screen. To have it print something on to the screen, we had to give it the things that we wanted printed. These things are nothing but parameters. We don't pass things to functions; we pass parameters to functions. So far we never created our own functions with parameters. In this program, we are calling the abc function with three things, with three parameters. The first is a number, the second is a logical value and the third is a string. So, we are passing the values 10, false and hell to the function abc(); These values must be stored somewhere, but where? When we create the function abc we have to state the names of three variables along with their respective data types. This is because the values that we pass will be stored in these variables. Hence we have the variables i, j and s. These are then displayed using WriteLine. Therefore, it will output 10, False and hell. This is how parameters are passed to functions in C#. Remember you decide what names to give to variables. Parameters passed to functions are also variables.
a.cs class zzz { static void Main() { abc(10,false); } static void abc(int i, bool j, string s) { System.Console.WriteLine("{0} {1} {2}", i,j,s); } } Compiler Error a.cs(4,1):error CS1501: No overload for method 'abc' takes '2' arguments

On compiling this program you will encounter the above error. Here we are calling abc with only two parameters, 10 and false. Whereas the function abc is actually created with three parameters. We are passing an erroneous number of parameters, hence the error. Lesson? One must pass the same number of parameters that the function has been created to accept. A mismatch between the number of parameters being passed and those being accepted will definitely assure you of an error. Thus as before, C# does a large number of error checks on your code. For, if it allowed the above function call to go ahead, what would the value of the third parameter s be? Now change the order of the values that are being passed. Your abc function should look like thisabc("hell",10, false);
a.cs class zzz { static void Main()

{ abc("hell",10,false); } static void abc(int i, bool j, string s) { System.Console.WriteLine("{0} {1} {2}", i,j,s); } } Compiler Error a.cs( 5,1): error cs1502: The best overloaded method match for 'zzz.abc(int, bool, string)' has some invalid arguments a.cs( 5,5 ): error cs1503: Argument '1': cannot convert from 'string' to 'int' a.cs(5,12): error cs1503: Argument '2': cannot convert from 'int' to 'bool' a.cs(5,15): error cs1503: Argument '3': cannot convert from 'bool' to 'string'

On executing this program you will be faced with the above errors. These errors have resulted due to a data type mismatch. It is somewhat like putting a round pole in a square peg! How is it going to fit? While calling the function abc() the first parameter that we are passing is the word "hell". But the function abc() has been created to accept the first parameter as an int. Remember we told you, not so long ago, that C# distinguishes between data types. Thus you can't store a string in a variable of type int. Similarly, the value 10 cannot be stored as a bool and false cannot be stored as a string. Therefore, not only should the number of parameters being passed and accepted be the same but also their data types must match. Like oil and water do not mix, in the same way you cannot give C# an int when it wants a string. As said earlier, some languages are more forgiving then C# due to which the programmer makes more mistakes in them.
a.cs class zzz { static void Main() { abc(); } } class yyy { static void abc() { System.Console.WriteLine("abc"); } } Compilation Error a.cs(5,1): error CS0103: The name 'abc' does not exist in the class or namespace 'zzz'

Seems like we are hooked on to errors! In this program we have created another class called yyy. We can have as many classes in one .cs file as we like. This program now has two classes, zzz and yyy. The class zzz has a function called Main. Main denotes the starting point of our code and as such is the first function to be called. The class yyy contains a function called abc. Here we are calling the function abc by saying abc(); in class zzz. But class zzz does not have any function by the name abc. Merely giving abc(); encourages C# to assume that abc() exists within the class zzz. But our abc function is contained in yyy. Hence we get an error as we are trying to call a function that exists in another class.

But we are adamant! We want to use the abc function that yyy has. It's human tendency to want things that others have! So, in the next program we are calling the function abc in the class yyy by writing yyy.abc();
a.cs class zzz { static void Main() { yyy.abc(); } } class yyy { static void abc() { System.Console.WriteLine("abc"); } } Compilation Error a.cs(5,1): error cs0122: 'yyy.abc() is inaccessible due to its protection level.

When we say yyy.abc(); why the dot? yyy is the name of the class and abc() is the name of the function . Each of these names can be as large as you want, so to separate them a dot is used. Thus when you want to access a function that belongs to another class you can do so by specifying the class name and function name separated by a dot. The dot is like the semicolon. The designers of the language wanted some character as a separator between class name and function name, they chose the dot, they could have also chosen the semicolon again. You will now realize why we say Console.WriteLine. Obviously, it means that Console is a class and within the class Console there is a function called WriteLine. But to your dismay, on executing this program you still get an error. Well, few people get what they want, however fewer still want what they get! You may want a particular thing but you will not get it unless the other party gives you the permission to take it, use it or share it. Your only other option is to put up a fight! We get an error here because we haven't used the word public. The whole idea behind C# is its usability on the net. And the only way you can use it on the net is by having security precautions. So in C# the default rule is - you can't use anything unless explicitly granted permission. Next question. How do you grant the necessary permission? Being its non-violent self, C# grants permission by using the word public. When we say public, we mean the world at large. So by starting with the word public we are saying that the whole world is now allowed to use this function as we are explicitly granting you rights. If you don't use the word public it will give you an access error. To rectify the error, add the word public just as we have done below.
a.cs class zzz { static void Main() { yyy.abc(); }

} class yyy { public static void abc() { System.Console.WriteLine("abc"); } }

Output abc

Finally, we have the correct code! See, one of life's greatest ironies is the fact that when you finally master a tough job, you make it look easy!! By using the word public in front of the function abc, we can now call it from zzz by specifying yyy.abc(); Now that the function is called, WriteLine displays 'abc'. Our next example will enhance your understanding further.
a.cs class zzz { static void Main() { yyy.abc(); abc(); zzz.abc(); } public static void abc() { System.Console.WriteLine("abc in zzz"); } } class yyy { public static void abc() { System.Console.WriteLine("abc"); } } Output abc abc in zzz abc in zzz Now we go a step further. In the above program we have two abc functions, one in class zzz and one in class yyy. If you want to call the one in yyy then you say yyy.abc(); but if you want to call the one in zzz then you say zzz.abc() or abc(). The function abc(), by itself, will ask which class is it? Since abc() is in zzz itself, C# assumes it to zzz.abc(); By implication, if the function exists within the same class, it is optional to preface the function with the name of the class. When you execute this program, yyy.abc() will call the abc function in class yyy and WriteLine will display 'abc'. Thereafter, both abc() and zzz.abc() will call the abc function in class zzz. And in each case WriteLine will display 'abc in zzz'. Thus if you do not preface the function name with the name of the class, C# will add the name of the class in which you are calling the function. In our case it is zzz.

2
Namespaces
Normally, students have an implicit trust in their teachers. For they know that if the blind lead the blind, both shall fall into the ditch. However, our philosophy is that a good teacher has to be an even better liar!! In accordance with this belief, initially we told you that WriteLine is the name of a function. Then we told you that the name is not WriteLine, it is System.Console.WriteLine. But even that's not true. Now comes the moment of truth. Console is actually the name of a class. Yes, trust us! There is no crying wolf here. The class Console has a function called WriteLine. Hence the name now becomes Console.WriteLine. However, that leaves out the word System. Now what does System mean? Well, a number of functions like WriteLine are available in C#. Some functions will let you print, some will enable writing of data to disk and others will let you create graphics. The problem that we are posed with is - how does one remember which function satisfies what purpose? Wouldn't it make sense if we logically grouped similar functions together? So, Microsoft thought that all functions that can write to the screen could be made part of one class. All functions that let you work with pictures could be part of another class. But even then, you will have too many functions in one class. So they thought of having a single higher logical group. Such that all the functions that have anything to do with the screen, i.e. whether you are drawing pictures or writing text, be grouped once again into a higher body. Thus all classes that deal with interacting with a database could go into a group called Data. The second problem that we are posed with is that of name clashes. What do we mean by that? Now, nothing can stop me from creating my own class called Console and include a function called WriteLine in it. But how will C# know which Console am I referring to? The one that we created ourselves, or the one that Microsoft has already created. In order to resolve these problems Microsoft decided to take classes and put them into namespaces. What is a namespace? It is simply a word. Thus we can logically group everything as per namespaces.

From the above explanation you would have by now guessed that System is nothing but a namespace. The following programs will help make this concept crystal clear.
a.cs class zzz { static void Main() { yyy.abc(); abc(); zzz.abc(); } public static void abc() { System.Console.WriteLine("abc in zzz "); } } namespace vijay { class yyy { public static void abc() { System.Console.WriteLine("abc"); } } } Compiler Error a.cs(5,1): error CS0246: The type or namespace name 'yyy' could not be found (are you missing a using directive or an assembly reference?)

In the above program, the only change that we have made is that we have now included the class yyy in a namespace called vijay. On doing so you will realize that the same program that worked earlier doesn't work anymore. This is because yyy is put in a namespace vijay. A namespace is nothing but a word with an open and close brace. The entire class is enclosed within the namespace. If you want to access a function belonging to class yyy from another class then the only way to do so is by saying vijay.yyy.abc(); Thus you specify the namespace first, then the name of the class followed by the name of the function, each of them separated by dots. Thus like Urdu, we read anything from the right and not the left. We start with the name of a function, then the name of the class and whatever is left is the namespace. Here zzz has not been given a namespace. If you don't specify a namespace then by default the class is included in a global namespace. Now change yyy.abc(); to vijay.yyy.abc() and watch the error disappear.
a.cs class zzz { static void Main() { vijay.yyy.abc(); abc(); zzz.abc(); } public static void abc() { System.Console.WriteLine("abc in zzz ");

} } namespace vijay { class yyy { public static void abc() { System.Console.WriteLine("abc"); } } } Output abc abc in zzz abc in zzz

We bet your faces are now beaming! Seems like the secret of happiness is not in doing what one likes to do but in liking what one has to do. We had to get rid of the error which we have succeeded in doing. The error has disappeared; the program executes as advertised and it generates the same output as it did previously. Thus all the classes and functions created by Vijay can be included in a namespace called vijay. If Sonal creates a namespace by her name then she can include all the functions and classes created by her in the namespace sonal. Thus there will be no name clashes at all. These namespaces that are created by us are called user-defined namespaces whereas System is a pre-defined namespace. Thus System is a namespace in which a class called Console was created, which contained a function called WriteLine. Thus the namespace concept allows us to create logical groups. So all xml related classes can be in a namespace called xml, web can be in a web namespace and so on and so forth. But the only problem now is that when you start writing code you have to specify the namespace first, then the class name followed by the function name. Well, everything is available but for a price! Our consolation is that it is a very small price to pay.
a.cs namespace mukhi { class zzz { static void Main() { vijay.yyy.abc(); abc(); zzz.abc(); mukhi.zzz.abc(); } public static void abc() { System.Console.WriteLine("abc in zzz "); } } } namespace vijay { class yyy { public static void abc()

{ System.Console.WriteLine("abc"); } } } Output abc abc in zzz abc in zzz abc in zzz

In the above program, we have two classes zzz and yyy. The class zzz is included in a namespace called mukhi and the class yyy is included in a namespace called vijay. So when we say abc(); in Main, Main is in zzz, so you are actually writing mukhi.zzz.abc(); This is because C# will automatically expand it since the function abc is available within the same class. Hence it is at your discretion as to how you want to write it. You can say abc(), zzz.abc() or mukhi.zzz.abc(); finally they all expand to namespace.classname.function name. C# adds the name of the namespace and the name of the class even if you do not specifically write it. The concept of namespaces is not very difficult to understand. It allows for a hierarchical grouping of classes. It tells us which classes are logically grouped. It also avoids classes from having the same name.
a.cs class zzz { static void Main() { Console.WriteLine("abc in zzz "); } } Compiler Error a.cs(5,1): error CS0246: The type or namespace name 'Console' could not be found (are you missing a using directive or an assembly reference?)

If we do not enclose our class in a namespace, it becomes part and parcel of the global namespace . This namespace does not contain a class called Console. We had mentioned earlier that the class Console is contained in the namespace System. We do not want to preface the Console class with the namespace System each and every time. The only reason being that our fingers will wear out typing the word System over and over again. So C# lets us use a shorthand by means of which we avoid the pain of having to keep on writing the name of a namespace over and over again.
a.cs using System; class zzz { static void Main() { Console.WriteLine("abc in zzz "); } } Output abc in zzz

The secret here is not in doing great things, but doing a small thing in a great way. We get no error simply by employing the word using which is part of the C# language. All that using does is whenever it

sees only the name of a class, it goes and adds (in this case) the word System. Thus we do not have to write the word System over and over again. This works the way shorthand does.
a.cs using System; class zzz { static void Main() { yyy.abc(); } } namespace vijay { class yyy { public static void abc() { Console.WriteLine("abc"); } } } Compiler Error a.cs(6,1): error CS0246: The type or namespace name 'yyy' could not be found (are you missing a using directive or an assembly reference?)

Now we get an error for yyy and not for Console as the yyy class belongs to the vijay namespace and not the global namespace. Because of the using keyword, C# adds the namespace System to yyy yielding System.yyy.abc and realizes that System does not contain a class called yyy. Hence the error.
a.cs using System; using vijay; class zzz { static void Main() { yyy.abc(); } } namespace vijay { class yyy { public static void abc() { Console.WriteLine("abc"); } } } Output abc

The error vanishes as C# first tries System.yyy.abc gets an error, then tries vijay.yyy.abc and is successful. Thus by having two using's we do not have to write the namespaces vijay or System ever again.
a.cs using System;

using mukhi; using vijay; namespace mukhi { class zzz { static void Main() { yyy.abc(); abc(); zzz.abc(); zzz.abc(); } public static void abc() { System.Console.WriteLine("abc in zzz "); } } } namespace vijay { class yyy { public static void abc() { System.Console.WriteLine("abc"); } } } Output abc abc in zzz abc in zzz abc in zzz

We can have as many using's as we like and the compiler will try each one in turn. If none of them match we will receive an error. In this case it will try 3 times with System, mukhi and vijay and if none match, you will get an error.
a.cs using System.Console; class zzz { static void Main() { WriteLine("abc in zzz "); } } Compiler Error a.cs(1,7): error CS0138: A using namespace directive can only be applied to namespaces; 'System.Console' is a class not a namespace

After the word using you can only write the name of a namespace. System.Console is a namespace class combination which is not allowed.

Building Hierarchy

In C# you organize classes using namespaces. Now let's discover the extent we can go to as far as organizing classes.
a.cs class zzz { static void Main() { mukhi.vijay.yyy.abc(); } } namespace mukhi { namespace vijay { class yyy { public static void abc() { System.Console.WriteLine("abc"); } } } } Output abc

In this program we have a namespace within a namespace i.e. within the namespace mukhi we have another namespace vijay. Thus namespaces are 'hierarchical'. If you want to access the function abc in yyy you have to specify it in the form- namespace.classname.functionname. So, the qualified name is now mukhi.vijay.yyy.abc(); Once the function is called, WriteLine will display 'abc'. In order to differentiate between the various names separated by dots, always read backwards. Reading backwards, the first is the function name then the class name and the names thereafter will all be namespaces. Alternatively, you can directly specify the namespace as mukhi.vijay, as we have done below. This program generates the same output as previously, it prints abc.
a.cs class zzz { static void Main() { mukhi.vijay.yyy.abc(); } } namespace mukhi.vijay { class yyy { public static void abc() { System.Console.WriteLine("abc"); } } } Output

abc

Here we have a single namespace by the name mukhi.vijay. The name mukhi.vijay is actually a shortcut for defining a namespace named mukhi that contains a namespace named vijay. In this program, we have only two namespaces. But you can expand it further to include a number of namespaces depending upon the level of hierarchy required by your program. We can liken this to an organization. Let's consider mukhi to be the name of the company. Within that you have a sub-company or a division called vijay, which creates it own classes. As such the level of hierarchy can be expanded. Before you understand the next program let's address a simple question. Why do you use classes? Classes are used because they offer a large number of functions. You don't use classes because of the variables that you can create within them; you use classes for the functions that they provide. Remember, you call a function using the form -namespace.classname.functionname.

File Operations
a.cs class zzz { static void Main() { File.Copy("c:\\csharp\\a.txt","c:\\csharp\\b.txt",true); } } Compiler Error a.cs(5,1): error CS0246: The type or namespace name 'File' could not be found (are you missing a using directive or an assembly reference?)

Our next program will enlighten you on something most sought after - The art of Copying. Ah! Finally something of interest! This program introduces the 'Copy' function. It allows you to duplicate a file. File is a class and it has a function called Copy, which is static. The first parameter 'a.txt' is the source file i.e. the file, which we want to duplicate. The second parameter 'b.txt' is the destination file i.e. the file that we want to copy to. Note that you must specify the entire path for the file name. The last parameter 'true' implies that if the file exists then it will be overwritten. If the file does not exist it will be created and contents of the source file will be copied onto it. And just when you thought you had mastered the art of copying the program returns with an error message. The error says C# does not know what File.Copy is. The problem is that the name of the namespace is System.IO. So you have to specify the namespace too. Add the namespace and execute the program.
a.cs class zzz { static void Main() { System.IO.File.Copy("c:\\csharp\\a.txt","c:\\csharp\\b.txt",true); } }

The program does not generate any compilation errors. Create a file called a.txt with some text before you run this program. Execute this program and then open the file 'b.txt'. Finally, the task has been accomplished! You now have the contents of a.txt copied into b.txt. Our next program introduces another function called 'Delete'.
a.cs class zzz { static void Main() { System.IO.File.Delete("c:\\csharp\\a.txt"); } }

The above program takes the name of a file as the parameter. This function will remove the file specified from disk. Give the dir command at the command prompt and you will find that the file has been deleted.
Every language will offer you millions of such functions like copy and delete. These functions were always available, but C# has gone one step further and made these functions a part of a Class. They are now part of a Namespace. Hence it becomes easier to categorize functions. It is but a question of detail whether you should or should not categorize them.

3
Constructors and Destructors New
Let's consider the following program.
a.cs class zzz { static void Main() { yyy.abc(); } } class yyy { public void abc() { System.Console.WriteLine("abc"); } } Compiler Error

a.cs(5,1) : error CS0120: An object reference is required for the nonstatic field, method or property 'yyy.abc()'

This program contains one class called yyy which has a function called abc. In Main() we are using the syntax yyy.abc() to call the abc function as we did earlier. Within the abc function we have the code for the function abc that will print the string "abc". On compiling this program you will get an error as incomprehensible as ever! But how is it that when we ran this program earlier we didn't get an error? If you are still bewildered, wake up and smell the coffee! Didn't you notice we removed the word 'static' while saying public void abc(). Hence we get an error. In our earlier programs when we wrote the function abc we had written the word static which is missing now. No, we are not going to tell you to add the word static and execute the program. We are not that predictable! On the contrary, we shall do something quite different and interesting. Keeping that in mind let's consider the next program.
a.cs class zzz { static void Main() { yyy a; a.abc(); } } class yyy { public void abc() { System.Console.WriteLine("abc"); } }

Compiler Error a.cs(6,1): error CS0165: Use of unassigned local variable 'a'

Before we look into this program let's get our basics clear. We have often used the statement 'int i' meaning that i was a variable that looked like an int. When we used the statement 'string s', it meant that s was a variable that looked like string. Similarly, in this program we are saying yyy a. This implies that 'a' looks like yyy. What is yyy? It is the name of a class. Here we do not call 'a' a variable, we call it an object. An object and a variable can be used interchangeably. Earlier, whenever we wanted to call a member from a class we would say yyy.abc(); i.e. class name dot function name. But in our current program we are saying a.abc(); We are using the same dot, but now it gives an error saying - 'Use of unassigned local variable'. Note that the word member is analogous with the word function. But things still don't seem any clearer. So, let's go a step further and add another statement a=new yyy(); Match your code with the one below.
a.cs class zzz { static void Main() {

yyy a; a=new yyy(); a.abc(); } } class yyy { public void abc() { System.Console.WriteLine("abc"); } } Output abc

The word or keyword new must be followed by the name of a class; You cannot substitute it with anything else, it must be a class. In our case, we have given the statement as new yyy(). yyy is the name of an existing class. But why have round brackets after the class name? The '(' and ')' brackets are part of the syntax. And you very well know by now that you can't argue with syntax. Thus it is at this point i.e. after saying new, that the object 'a' that looks like yyy is created. We could have also called the object 'a' an instance of the class yyy. Since the class yyy has only one function it will allocate memory for THAT one function ONLY. Now we have an object 'a' that looks like class yyy. Once the object is created, it can be used to access the function from class yyy. Hence, now if we say a.abc() we will not get an error. Thus an object is nothing but an instance or an occurrence of a class. Therefore, 'a' is an instance of the class yyy. This is how you can instantiate an object. In order to create an object you must use the keyword 'new'. Our next program will help you gain a better understanding of this concept.
a.cs class zzz { static void Main() { int i; i=new int(); } }

At first we have int i, meaning i looks like int. Then we have i=new int(); Executing this program will not generate any errors. But so far whenever we used int i we never created the object i using new int(). This is because C# does this internally for us. It saves us the trouble of doing so. Then why doesn't C# do so for all the other objects that we create? This is because C# recognizes only two types of classes. The first type is one that the C# compiler knows of in advance. int, long, bool, and string are classes that fall into this category. These are predefined classes. But we call them data types because in C and C++ they were called data types and C# has a legacy of C and C++. So technically, when we say int i it does i=new int(); internally. The second type of classes that C# recognizes are the ones that we create i.e. user-defined classes. For user-defined classes we have to create objects ourselves. Thus anything other than the basic data-types must be explicitly created.

So when we say 'yyy a' we are not creating the object at this point. We are only declaring the object to be of type yyy. It is only when we use the word 'new' that the object is created and memory is allocated for the same. Therefore, when we have our own classes, that's the time we use new. Without new you cannot create an object.

Static
You are certainly going to benefit by the patience you have shown so far. To find out how, let's follow the next program.
a.cs class zzz { static void Main() { yyy a; a=new yyy(); a.abc(); yyy.pqr(); } } class yyy { public void abc() { System.Console.WriteLine("abc"); } public static void pqr() { System.Console.WriteLine("pqr"); } } Output abc pqr

In this program we have two functions abc and pqr. It is of significance to note that the function pqr has the word static whereas abc does not. If you want to access the static function pqr you say yyy.pqr() and to access the non static function abc you say a.abc(); You can't do the reverse i.e. you cant say a.pqr() and yyy.abc().
a.cs class zzz { static void Main() { yyy a; a=new yyy(); yyy.abc(); a.pqr(); } } class yyy { public void abc() { System.Console.WriteLine("abc"); }

public static void pqr() { System.Console.WriteLine("pqr"); } } Compiler Error a.cs(7,1): error CS0120: An object reference is required for the nonstatic field, method, or property 'yyy.abc()' a.cs(8,1): error CS0176: Static member 'yyy.pqr()' cannot be accessed with an instance reference; qualify it with a type name instead

The word 'static' implies 'free'. Static signifies that you can access a member or a function without creating an object. At last you are enjoying the fruits of patience! Observe that the function Main in zzz is static. This is because we are not creating any object that looks like zzz. The crux is that if you don't want to use 'new' and yet use the function then you must make the function static. In both cases a dot is used to reference the function. The only difference is that a static member belongs to the class and as such we don't need to create an object to access it. On the other hand, a non-static member, that is the default, can be accessed only via an object of the class. Thus WriteLine is a static function in Console as we did not create an object that looks like Console to access it.
a.cs class zzz { static void Main() { System.Console.WriteLine(yyy.i); } } class yyy { public int i = 10; } Compiler Error a.cs(5,26): error CS0120: An object reference is required for the nonstatic field, method, or property 'yyy.i'

Why did we get an error? Think for thinking is the hardest work there is, which is probably the reason why so few engage in it. If you still haven't got it, let us enlighten you. The same rules for static apply to functions as well as variables. Hence we get the above error.
a.cs class zzz { static void Main() { yyy a = new yyy(); yyy b = new yyy(); a.j = 11; System.Console.WriteLine(a.j); System.Console.WriteLine(b.j); yyy.i = 30; System.Console.WriteLine(yyy.i); } }

class yyy { public static int i = 10; public int j = 10; } Output 11 10 30

A static variable belongs to the class. Hence if we create a static variable i, no matter how many objects we create that look like yyy, there will be one and only one value of i as there is only one variable i created in memory. Thus we access a static variable by prefacing with the name of the class and not name of object. If the variable is non-static like j then we have to use the syntax as explained earlier i.e. name of object dot name of variable. Thus each time we create an object that looks like yyy we are creating a new/another copy of the variable j in memory. We now have two j's in memory one for a and another for b. Thus j is called an instance variable unlike i. When we change the variable j of a to 11, the j of b remain at 10. Thus functions are created in memory only once, irrespective of the word static. If a class has no instance or non static variables then it makes no sense to create multiple instances of the object as there will be no way of distinguishing between the copies created.

Constructors
a.cs class zzz { public static void Main() { yyy a; System.Console.WriteLine("Main"); a=new yyy(); } } class yyy { public yyy() { System.Console.WriteLine("yyy"); } } Output Main yyy

In the above program we have a class called yyy. We also have a function called yyy which happens to be having the same name as the name of the class. We have a friend named Bunty. Coincidentally, the name of his pet dog is also Bunty! Similarly, it is absolutely legal to have a function by the same name as that of the class. In this case first we see Main and then we see yyy displayed on the screen which means that the function yyy() gets called automatically. Note, we have not called the function yyy explicitly. This happens to be a special function and it is called a 'constructor'.

Initially we are saying yyy a. By doing so we are specifying that 'a' looks like yyy. We are not creating an object that looks like yyy. The next statement has System.Console.WriteLine, which will print 'Main'. Thereafter, using new we are creating an object a. It is at this point that C# calls the constructor i.e. it calls the function yyy(). Now you will see 'yyy' displayed. This goes to prove that as soon as an object of a class is created, C# automatically calls the constructor. A constructor gets called at the time of birth or creation of the object. It has to have the same name as the name of the class.
a.cs class zzz { public static void Main() { yyy a; System.Console.WriteLine("Main"); a=new yyy(); a.yyy(); } } class yyy { public yyy() { System.Console.WriteLine("yyy"); } } Compiler Error a.cs(8,1): error CS0117: 'yyy' does not contain a definition for 'yyy'

Here, we are calling the function yyy using the appropriate syntax i.e. by saying a.yyy(). Now, run the compiler. Baffled by the error? The error says 'yyy' does not contain a definition for 'yyy'. The class yyy does contain a function called yyy which got called in the previous example. Has C# developed amnesia all of a sudden? What went wrong? Well, you cannot call this function using a.yyy() or yyy.yyy() The catch is that when you have a function with the same name as that of the class you cannot call it at all. It gets called automatically. C# does not give anyone the authority to call such a function. It calls this function automatically only at birth. Seems abnormal doesn't it! But what is the purpose of having constructors? A constructor can be used in cases where every time an object gets created and you want some code to be automatically executed. The code that you want executed must be put in the constructor. That code could be anything, it could check for hard disk space, it could create a file or it could connect to the net and bring a file over. What that code will do shall vary from person to person. To understand how and when the constructor gets called, let's take into consideration our next example. Now remove the word 'public' in front of yyy() as we have done below.
a.cs class zzz { public static void Main() { yyy a; System.Console.WriteLine("hi"); a=new yyy(); } }

class yyy { yyy() { System.Console.WriteLine("yyy const"); } } Compiler Error a.cs(7,3): error CS0122: 'yyy.yyy()' is inaccessible due to its protection level.

Obviously, you will get an error. This is because without the word public the function is private property. And when you trespass on private property you have to face the consequences. In our case we are faced with an error. By making the function public every one can use it, it is now becomes public property! If the constructor is private then nobody can create an object that looks like yyy. Do you think constructors can return values? Let's try it out and find out for ourselves.
a.cs class zzz { public static void Main() { yyy a; System.Console.WriteLine("hi"); a=new yyy(); } } class yyy { public int yyy() { System.Console.WriteLine("yyy const"); } } Compiler Error a.cs(12,12): error CS0542: 'yyy': member names cannot be the same as their enclosing type

Executing the above program generates an error. It says that member i.e yyy cannot be the same as the enclosing type i.e class yyy. Now, that is an error that you certainly didn't expect. Let us analyze why we got this error. Here we are saying public int yyy implying that the function yyy() is returning an int. yyy() is a constructor and is called automatically at the time an object is created. If a constructor is to return a value then to whom should it return the value to? Since it is called automatically, there is nothing that can accept the return value. Thus constructors cannot return values. Also when a constructor gets called, an object is in the act of being created. It has not yet been created. The keyword new first allocates memory for the functions and the variables. After this it calls the constructor. When the constructor finishes, then we say that the object has been created. Thus the constructor has no one to return values to. Now that we know constructors don't return values let's return void instead.
a.cs class zzz {

public static void Main() { yyy a; System.Console.WriteLine("hi"); a=new yyy(); } } class yyy { public void yyy() { System.Console.WriteLine("yyy const"); } } Compiler Error a.cs(12,13): error CS0542: 'yyy': member names cannot be the same as their enclosing type

Though we are returning void, we get the same error. This is because C# is very sure of what it says. When you borrow from other people you do so on the pretext that you will return it. It's a different story that you never do! You rarely mean what you say. But when C# says that constructors cannot return values it means 'constructors cannot return values', not even 'void'. Remember, there is nothing that can accept the return values. Hence even void cannot be accepted. When a function returns a void we mean that it will return no value at all. For a constructor, the word return makes no sense at all.

Constructors with parameters


Just as we pass parameters to other functions, you can also pass parameters to constructors.
a.cs class zzz { public static void Main() { yyy a; System.Console.WriteLine("hi"); a=new yyy("no"); } } class yyy { public yyy() { System.Console.WriteLine("yyy const"); } } Compiler Error a.cs(7,3): error CS1501: No overload for method 'yyy' takes '1' arguments

You are already aware of the fact that parameters are passed to functions while calling them. Similarly, we will pass a parameter to the constructor yyy while creating the object a; because it is at this point that the constructor gets called. Hence we are saying a=new yyy("no"). But on compiling this program you get an error. Here, the constructor is being called with a string 'no' as a parameter. But there is no variable in the constructor yyy to store the value 'no'. Add 'string s' in the constructor yyy and watch the error disappear.
a.cs

class zzz { public static void Main() { yyy a; System.Console.WriteLine("hi"); a=new yyy("no"); } } class yyy { public yyy(string s) { System.Console.WriteLine(s); } } Output hi no

At first WriteLine will display 'hi'. Then we have a constructor yyy that takes a string 'no' as a parameter and accepts it in a variable s. Thus the moment the constructor yyy is called 'no' will be displayed. This is because the constructor yyy contains code that will print the value stored in the variable s. This is how constructors with parameters are called. So far we created only one instance of the class yyy. In the following program we are creating two instances of the class yyy, 'a' and 'b'.
a.cs class zzz { public static void Main() { yyy a,b; System.Console.WriteLine("hi"); a=new yyy("no"); b=new yyy(); } } class yyy { public yyy(string s) { System.Console.WriteLine(s); } }

Compiler Error a.cs(8,3): error CS1501: No overload for method 'yyy' takes '0' arguments

While creating the object 'a' the constructor yyy is being passed a parameter 'hi'. In case of the object 'b' the constructor will be called without any parameters. But in our program we have code only for the constructor with parameters. Try executing this program and you will get an error saying that method yyy takes 0 arguments. This is because we do not have code for the constructor without parameters. Let's understand the reason behind the error.

In our earlier programs, we did not specify a constructor. A relevant question here would be - how did the objects get created then, without the constructor being called? C# is a Good Samaritan, at that time it inserted a free constructor. It does so internally. On its own it inserts a constructor without any parameters, without any code into the class. It looks like thisyyy() { }

Point to ponder - in the above program, when we didn't create a constructor without parameters why didn't we get one free? Remember we said C# is a Good Samaritan? And Good Samaritans help the needy. On seeing that we already have a constructor with parameters, C# looks the other way i.e., it takes the free one away. However, it is only when you have no constructor at all that C# melts its heart and gives you one free. Remember, even if it finds that you have even one constructor it will take away the free one. On the assumption that if you can provide one constructor, then with a little effort you can work towards providing the others too! Now the only way to get rid of the error is to add the constructor yourself.
a.cs class zzz { public static void Main() { yyy a,b; System.Console.WriteLine("hi"); a=new yyy("no"); b=new yyy(); } } class yyy { public yyy(string s) { System.Console.WriteLine(s); } public yyy() { System.Console.WriteLine("bad"); } } Output hi no bad

Here, initially, the two objects 'a' and 'b' are declared. In the next statement we have WriteLine, which will display 'hi'. We are then creating the object a. At this point the constructor with a string as a parameter is called. It will now display the value stored in the variable s which is 'no'. Thereafter, the object b is created. At this point the constructor without the parameters will be called. This constructor contains the WriteLine statement, which will print 'bad'. Here, we have as many constructors as we are calling and hence we do not get any errors.

So, essentially, a constructor is a special function that gets called when an object is created. It does not return any values, not even void. As far as parameters go it behaves like a normal function. If no constructors are specified you get one free, otherwise, you need as many constructors as you are calling. Hence in the above case we cannot create an object as new yyy(100) as we do not have a constructor that accepts one int as a parameter.

Destructors
a.cs public class zzz { public static void Main() { aa a = new aa(); } } public class aa { public aa() { System.Console.WriteLine("Constructor "); } ~aa() { System.Console.WriteLine("Destructor"); } } Output Constructor Destructor

A destructor is a function with the same name as the name of a class but starting with the character ~. A constructor gets called at birth whereas a destructor gets called at death. In C# unlike other languages we do not know when an object dies as unlike James Bond, we do not have a license to kill. Thus even though the object a dies at the end of main, the destructor may not get called. Thus, in C# we cannot decide when the destructor gets called. This decision to call the destructor is made by a program within C# called the garbage collector. The concept first gained currency with the advent of Java. In Java and C# we cannot remove our objects from memory. Thus it is for the garbage collector to decide when to call the destructor. The programming world was replete with errors mainly because programmers use new to allocate memory and then forget to deallocate it. This gave rise to a concept called memory leaks. On the flip side of the coin, programmers deallocated the memory, forgot about it and then accessed the object again. This generates an error occurring at random and difficult to pin down.
a.cs public class zzz { public static void Main() { aa a = new aa(); } } public class aa { public aa() {

System.Console.WriteLine("Constructor"); } public ~aa() { System.Console.WriteLine("Destructor"); } } Compiler Error a.cs(14,9): error CS0106: The modifier 'public' is not valid for this item

A destructor cannot have any modifiers like public preceding it.


a.cs public class zzz { public static void Main() { aa a = new aa(); } } public class aa { public aa() { System.Console.WriteLine("Constructor"); } ~aa(int i) { System.Console.WriteLine("Destructor"); } } Compiler Error a.cs(14,5): error CS1026: ) expected a.cs(14,10): error CS1002: ; expected a.cs(16,25): error CS1519: Invalid token '(' in class, struct, or interface member declaration a.cs(18,1): error CS1022: Type or namespace definition, or end-of-file expected

Constructors come in plenty with different numbers of arguments being passed to them. However, in the case of destructors, one size fits all, i.e., they come in only one size, with no parameters. Here we created a destructor with an int as a parameter thereby confusing the C# compiler completely. C# lacks true synchronous or deterministic destructors i.e. destructors being called at a certain point in time. You cannot have your life depend on when a destructor would be called. The common grouse against C# is that unlike C++ it does not support true destructors.
a.cs public class zzz { public static void Main() { aa a = new aa(); } } public class aa { public aa() { System.Console.WriteLine("Constructor");

} ~aa() { System.Console.WriteLine("Destructor"); } protected override void Finalize() { } } Compiler Error a.cs(18,25): error CS0111: Class 'aa' already defines a member called 'Finalize' with the same parameter types

We tried to create a function called Finalize. The compiler comes back and tells us that we already have a function called Finalize. This is weird as we have only one Finalize function. The reason for this error is that the compiler converts our destructor from ~aa to Finalize.

Arrays
All programming languages embrace the concept of arrays. An array is nothing but more of one entity i.e., a multiple of the same type. Simply put, when we have five books, we don't just say we have five books. Instead we say we have an array of five books. So, whenever you want to store multiple values of variables you store them in an array.
a.cs class zzz { public static void Main() { int[] a; a= new int[3]; a[0]= 1; a[1]= 10; a[2]= 20; System.Console.WriteLine(a[0]); a[0]++; System.Console.WriteLine(a[0]); int i; i=1; System.Console.WriteLine(a[i]); i=2; System.Console.WriteLine(a[i]); } } Output 1 2 10 20

Here 'a' is an array of ints. You declare arrays with a set of [] brackets. At this point it is not known how large the array will be. For that we have a=new int[3]; after new we have int meaning we want to create a variable of type int. We are putting 3 in the square brackets meaning we want to store 3 ints. This will create three ints a[0], a[1] and a[2]. They are then initialized to the values 1,10 and 20 respectively. To initialize an array variable we use the name, i.e. in this case a and follow it with the open and close []

brackets. Inside them we put the array number. The first variable is called a[0] , the second a[1] and so on. C# like most computer programming languages likes to start counting from 0 and not 1. Therefore, the last variable is a[2] and not a[3]. Since an array is many of the same type, they all have the same name. In our earlier example, even if we have many books, all the books will be called books. However, to refer to them individually you can say book1, book2, book3 etc. WriteLine will display the value stored in a[0] which is 1. a[0]++ will increment the value stored in a[0] by one. WriteLine will now display 2. Thereafter, the variable i is declared as an int. It is then initialized to 1. Within the WriteLine function we have a[i]. It is not specifically stated which variable, instead we have said a[i]. There is no variable called a[i], but i has a value 1, so it is read as a[1]. Hence the value stored at a[1], which is 10, is displayed. The next WriteLine will display the value stored in a[2] as i is reinitialized to 2. Doing this makes our program more generic. We haven't specifically stated which variable, we are letting a variable called i decide the name of the variable. The next example demonstrates how arrays can be used within loops.
a.cs class zzz { public static void Main() { int[] a; a= new int[3]; int i; for( i=0; i<=2; i++) a[i]= i*10; for( i=0; i<=2; i++) System.Console.WriteLine(a[i]); } } Output 0 10 20

The advantage of using arrays is that you can decide the name of the variable later and they can also be used in loops. Here 'a' is an array of ints and i is a variable of type int. The array size is 3 i.e. it can store three ints. The first for loop is used to initialize the individual array items. Within the for loop, i is initialized to 0. The condition i<=2 indicates that the loop will execute thrice. So, when the control enters the for loop, for the first time i is 0. Looking at the right hand side of the expression, i*10 will now read as 0*10, which is 0. Hence, a[i] which is read as a[0] will be initialized to 0. i++ increments the value of i to 1. The second time a[i] will be read as a[1] which will be initialized to 10. Thereafter, a[i] will be read as a[2] and initialized to 20 as i is now 2. Now i will be 3, so the condition evaluates to false and the loop terminates. The second for loop displays the values stored in the array. This is similar to the above loop. Here we are displaying the values of the individual array items. As the for loop executes, WriteLine will read a[i] as a[0], a[1] and a[2] in each case. As such, WriteLine displays 0,10,20. So, starting from the beginning and going upto the end, all the values stored in the array are displayed.

Arrays can also be used in a foreach statement. This is exemplified in the following program.
a.cs class zzz { public static void Main() { int[] a; a= new int[3]; a[0]= 1; a[1]= 10; a[2]= 20; foreach ( int i in a) System.Console.WriteLine(i); } } Output 1 10 20

The foreach statement lists the elements of the array. It executes a statement for each element of the array or collection. 'a' is an array of type int that can store three items. a[0], a[1] and a[2] are the elements or items of the array. They have been initialized to 1, 10 and 20 respectively. In the foreach statement we have ( int i in a ). i is a variable of type int and a is the array created earlier. The first element of the array 'a' is a[0] and it holds the value 1. The foreach statement picks up this value and stores it in i. Since i now holds the value 1, WriteLine displays 1. The second element is a[1]. It picks up its value, which is 10 and stores it in i. Thus i now holds the value 10. WriteLine will now display 10. This goes on for all the elements of the array. Our array 'a' comprises three elements. Hence the foreach will execute the WriteLine statement for each of them and display their values 1,10 and 20. The variable i is only available in the foreach. The foreach makes it easier for us to run through all the members of any array.

Parameters Revisited with Out and Ref


Variables are the cornerstone of programming languages. In a way, they are like items contained in a bag. You can put an item in a bag, remove it therefrom, or replace it with another. Our next few programs shall be explained along these lines.
a.cs class zzz { public static void Main() { int i=100; yyy a; a=new yyy(); a.abc(i); System.Console.WriteLine(i); } } class yyy { public void abc(int i)

{ System.Console.WriteLine(i); i=10; } } Output 100 100

'a' is an object that looks yyy. The variable 'i' is initialized to a value 100. Then the object 'a' that looks like yyy is created. We are now calling the function abc with one parameter 'i'. Within the abc function we are printing the value of i. When we call the function abc from Main, i had a value 100. So the variable i in abc also has a value 100. Thus WriteLine will display the value 100. We are now assigning i a new value 10. But the i that changes is the parameter i in abc, and not the i of Main in zzz. It's like having two similar bags, where you change the contents of only one. So the WriteLine in Main will again print 100. Thus the variable i within the abc function is temporary. It exists only within the '{' and '}' braces of the function. Therefore, this 'i' is local to the function. Its value is not available in Main. It's like your memory, temporary. It exists as long as you are reading this book. Once the book is over everything is forgotten! Thus please do not call the variable i in abc as i because it will confuse everyone. Thus i in abc has nothing to do with the i in Main. Ergo, changing i in abc will have no effect on the i in Main. But a situation could arise wherein you would like the function abc to change the value of i. In this context you are saying, I am giving a variable to a function abc, use it, but I would also like the function abc to change it. And once its value is changed in the function, it i.e. the changed value should be available in Main. Let's see how we can handle a situation like that.
a.cs class zzz { public static void Main() { yyy a; int i=100; a=new yyy(); a.abc(i); System.Console.WriteLine(i); } } class yyy { public void abc( out int i) { i=10; } } Compiler Error a.cs(8,1): error CS1502: The best overloaded method match for 'yyy.abc(out int)' has some invalid arguments. a.cs(8,7): error CS1503: Argument '1':cannot convert from 'int' to 'out int'.

This program is exactly like the previous one. The only change is that we added the word 'out' in the function abc along with the parameter i. We get an error on compiling this program. You realize, we are saying a.abc(i) in Main, but in the function we are saying abc(out int i). 'out' is the key to solving our

previous problem. 'out' means whatever changes you will make in abc, they will be visible outside the function also. Note that it doesn't matter what you call the variable in the function abc, the original will change. So, instead of saying abc(out int i) you could have used another variable. In that case, if you said abc(out int p) it would be absolutely legal. To do away with the error you must specify 'out' while calling the function as well. Now we have rewritten the program with the above change.
a.cs class zzz { public static void Main() { yyy a; int i=100; a=new yyy(); a.abc(out i); System.Console.WriteLine(i); } } class yyy { public void abc( out int i) { i=10; } } Output 10

In this program, we now have 'out' in both cases: in the function call and the function itself. So by saying a.abc( out i) you are implying that you are allowing the function abc to change the value of i. Then in the function definition we also have the word 'out', so it knows i is going to change and hence i now changes in the original. Therefore, WriteLine will displays the new value 10. We are now using the word 'ref' instead of 'out'. Let us see the effects of doing so.
a.cs class zzz { public static void Main() { yyy a; int i=100; a=new yyy(); a.abc(ref i); System.Console.WriteLine(i); } } class yyy { public void abc( ref int j) { j=10; } } Output 10

This program executes smoothly and gives the same output as previously. It displays the value 10. So in that sense 'ref' is like 'out'. In either case the original value of 'i' changes. Thus, if you are calling the function with 'ref' then state 'ref' in the function also. If you are calling the function with 'out' then give 'out' in the function also. Game for some experimentation? Let's try to execute the above program without initializing the variable i.
a.cs class zzz { public static void Main() { yyy a; int i; a=new yyy(); a.abc(ref i); System.Console.WriteLine(i); } } class yyy { public void abc(ref int j) { j=10; } } Compiler Error a.cs(8,11): error CS0165: Use of unassigned local variable 'i'

Here we are saying int i. Note that we are not initializing i. We are using 'ref' which gives us an error. The error says 'use of possibly unassigned local variable i'. Here we didn't initialize i and yet we are trying to use it; hence we get an error. Now, let's look at the next example. Here we have the same program only now we are using 'out' instead of ref.
a.cs class zzz { public static void Main() { yyy a; int i; a=new yyy(); a.abc(out i); System.Console.WriteLine(i); } } class yyy { public void abc(out int j) { j=10; } }

Output 10

In this program we haven't initialized i either but this time we don't get any error. This goes to show that when using 'ref' the variable must be initialized and only then can you change its value. In case of 'out' you don't have to initialize the variable to change its value. But why have this differentiation? This is because in case of 'ref' you can read the value of the variable as well as write to it. Therefore, if one has to read the value of the variable, it must be initialized before hand. But it is your discretion whether you want to change the value, read it or do both. But in case of 'out' you can only write i.e., you can only change the value of the variable, you cannot read it. So, in case of 'out' since it does not read the variable it doesn't matter even if it is not initialized. This is further exemplified with the help of the next few programs. In the following program we have initialized i. Note here we are using 'out'.
a.cs class zzz { public static void Main() { yyy a; int i=10; a=new yyy(); a.abc(out i); System.Console.WriteLine(i); } } class yyy { public void abc( out int j) { System.Console.WriteLine(j); j=10; } } Compiler Error a.cs(16,26):error CS0165: Use of unassigned local variable 'j'

Within the function abc we are first printing the value of i using the WriteLine statement. That means we are trying to read the value of i which is passed to the variable j in the function abc. But with 'out' one cannot read values hence we get an error. Now if you try the same program with 'ref' instead of 'out' you will not get any errors. This is because with 'ref' you can read the values as well as well as change them. However do note that all 'out' parameters must be initialized or else you will get an error form the compiler as follows.
a.cs class zzz { public static void Main() { yyy a;

int i=10; a=new yyy(); a.abc(out i); System.Console.WriteLine(i); } } class yyy { public void abc( out int j) { } } Compiler Error a.cs(14,13): error CS0177: The out parameter 'j' must be assigned to before control leaves the current method

So where can we use 'out'? We can use 'out' if we want the function to make some calculations and fill up the variable.
a.cs class zzz { public static void Main() { yyy a; int i=10; a=new yyy(); a.abc( out i ); System.Console.WriteLine(i); } } class yyy { public void abc( out int i ) { i= 20 * 20; } } Output 400

In this program we are using 'out'. We are multiplying 20 by 20 and storing the result 400 in i. Thereby the value of i is changed and WriteLine will now print 400. Our next example will make things as clear as daylight.
a.cs class zzz { public static void Main() { yyy a; int i=10; int k=20; int m; a=new yyy(); m=a.abc( out i, out k ); System.Console.WriteLine(i);

System.Console.WriteLine(k); System.Console.WriteLine(m); } } class yyy { public int abc( out int x, out int y) { int j; x=30;y=10; j=x * y; return j; } } Output 30 10 300

After specifying that a looks like yyy, the two variables i and k are initialized to the values 10 and 20 respectively. Then the object a is created. The third variable m is of type int and is used to store the return value of the function abc. By using 'out', the function abc is called with two parameters, i and k. The abc function has the variables x and y. Within the function another variable j is declared of type int. The variables x and y are assigned new values 30 and 10 respectively. Their values are multiplied and stored in j, i.e. 300. The next statement return j will yield the value of j, which is stored in m. Now WriteLine will display the value of i as 30. This is because with the abc function we filled up i with the value 30. Similarly, the next WriteLine statement will print the value of k, which is 10. Then we print the value of m, which is 300. In a nutshellIn case of both 'ref' and 'out' the original changes. A point to note is that when we say 'ref' it means we will initialize the variable. The abc function expects the variable to be initialized so that the function can use the value of the variable. When the variable changes the change is reflected outside. So, whenever you say 'ref' the variable has to be initialized, otherwise an error occurs. The function will assume that the variable is initialized because it expects to read the value. You may choose to read the value or change it or do both. But when you say 'out' it implies that we are not going to initialize the variable, that the abc function is not going to use the value, it is only going to change the value. When there is an 'out', abc can use the variable even if it is not initialized. This is because you cannot read the value in case of an 'out' variable; the function can only change the value. In other words, it has to change the value of the variable to avoid any errors.

4
Components and Database Handling
Exception Handling
Failing to prepare is preparing to fail. Ergo, one is constantly planning and preparing for the future. We often set a path for ourselves and try to follow it steadily. But then life intervenes. Uncertainties in life result in unforeseen situations. These are like exceptions in the normal course that we set for ourselves. Similarly, when you write programs, unforeseen problems may arise during its normal path of execution. These unforeseen problems are nothing but an euphemism for errors. Just as in life, in the programming world, these errors can be further classified into Fatal errors and Non-Fatal errors. A Fatal error is an error that brings the program to a grinding halt. A Non-Fatal error is an error that allows your program to run but with limited capacity. This can be exemplified by the following. Let's assume you have a card that is not of a high resolution. Accordingly, your browser displays your page in a lower resolution. Now, technically, that is an error but it is not a Fatal one. However, if you didn't have a graphics card at all then it would be a Fatal error. Thus, we may also call an unforeseen problem or error an Exception. In other words, therefore, the word Exception is used almost synonymously with the word Error. Earlier, the problem was that we never centralized error handling. Let's assume you have to open three files. Each time you open a file you have to check whether an error occurred or not. So you have to conduct that check for every file. Since there are three files, it would mean repeating the same error check thrice. That is surely a waste of time. Or you could be calling two functions and checking for the same error in both the functions. One reason that programmers don't write error-handling routines is that they get tired of the mundane task. It is the same thing repeated over and over again. Let's consider constructors. Before the constructor gets called, the object has not yet been created. So you ask the constructor to create an object, to allocate memory and create a file. Now, if it can't do so, how will the constructor return to tell you that an error occurred! Today constructors carry a lot of code within them and if you haven't forgotten, constructors cannot return values. Because of the various reasons discussed above, we don't talk about errors any more; we handle exceptions. Bearing this in mind let's understand the next program.
a.cs class zzz { public static void Main() { yyy a; a=new yyy(); a.abc(); System.Console.WriteLine("Bye");

} } class yyy { public void abc() { throw new System.Exception(); System.Console.WriteLine("abc"); } } Compiler Warning a.cs(16,1): warning CS0162: Unreachable code detected Output Unhandled Exception: System.Exception: Exception of type System.Exception was thrown at yyy.abc() at zzz.Main()

Here, a.abc calls the function abc in class yyy. System.Console.WriteLine is used to display 'Bye'. It is of significance to note that when you run this program the System.Console.WriteLine does not get called. Hence the word 'Bye' is not displayed. Within the abc function we have a line that says throw new System.Exception(); The word new indicates that we are creating an object. We are creating an object that looks like System.Exception. 'throw' is a reserved word, that means it is recognized by C#. Exception is a class in the System namespace. In other words, we are identifying an exception, creating an object of it, and throwing it. Then we have a WriteLine statement for printing 'abc'. Note that neither 'Bye' nor 'abc' gets displayed. A Message Box may appear for debugging the applicaition. Since we are still at the learning stage, we click on the No button. The warning says that when you use the 'throw' keyword in your code, no lines of code get called after that. Since the function abc is throwing an exception no code after the throw in abc will get executed. The throw acts like the return statement. Everything comes to a stand still! And we get an error at runtime and not at the time of running the compiler; indicating where the exception occurred. Also no code gets called after function abc gets called as it throws an exception. Explicitly declaring exceptions tells the compiler that a particular problem might occur. When the problem does occur, an exception is thrown; the next step being to catch the exception. Let's see how we can accomplish this. In our program, the function abc throws an exception. We will now catch the exception.
a.cs class zzz { public static void Main() { yyy a; a=new yyy(); try { a.abc(); System.Console.WriteLine("Bye"); } catch (System.Exception e) { System.Console.WriteLine("In Exception"+ e.ToString()); } System.Console.WriteLine("After Exception"); } } class yyy {

public void abc() { throw new System.Exception(); System.Console.WriteLine("abc"); } } Output In ExceptionSystem.Exception: Exception of type System.Exception was thrown. at yyy.abc() at zzz.Main() After Exception

Catching exceptions is done within 'try-catch' blocks. Therefore, the code for abc is included within a 'try-catch' block. a.abc - the function that throws the exception - is included within the try-catch block . The abc function throws an exception by using the keyword throw. There is no other way of throwing an exception. At this point all code is skipped in function abc as well as the in the try block and the control moves to the catch block. As such, neither 'abc' nor 'bye' gets displayed. Within the catch we have a parameter 'e' that looks like System.Exception. The object e has a method called ToString. ToString is a very handy function. It tells you where exactly the exception occurred and in which function, function within function. So, System.Console.Writeline will display the string 'In Exception' along with the exception. After the code contained in the catch block is executed, the remaining code after the end of the try catch block will be executed. Hence, WriteLine will display 'After Exception'. That means the program will not come to a stand still, it resumes execution after the catch and not after the function which threw the exception. If you give a return statement immediately after the catch block, as we have given in the next program, the program will stop execution there itself. Hence, in this case, 'After Exception' will not be displayed as shown below.
a.cs class zzz { public static void Main() { yyy a; a=new yyy(); try { a.abc(); System.Console.WriteLine("Bye"); } catch (System.Exception e) { System.Console.WriteLine("In Exception"+ e.ToString()); return; } System.Console.WriteLine("After Exception"); } } class yyy { public void abc() { throw new System.Exception(); System.Console.WriteLine("abc"); } }

Output In ExceptionSystem.Exception: Exception of type System.Exception was thrown. at yyy.abc() at zzz.Main()

Each time that abc gets called an exception is thrown. But you may not want that to happen. Hence, exception handling is normally included in an if statement and if an error condition takes place. A 'try-catch' block can include a number of functions and whenever an exception occurs for any one of them, we will catch it. By doing so we are synchronizing all the code to handle errors at one place. Constructors can also throw exceptions.

Building Components
a.cs public class zzz { public void abc() { System.Console.WriteLine("zzz abc"); } }

The above program consists of a simple class zzz with one public function. The class has also been tagged with the modifier public that makes it accessible to everyone. When we run the command csc a.cs, we are asking the C# compiler to create an executable file for us even though we did not explicitly ask it to. An executable file will always be created by the C# compiler unless you override it by stating an option to the C# compiler. Let us start with the /t option.
csc /t:library a.cs

You could use /t or /target. This option specifies what type of output file the compiler should create for you. If you do not specify a /t option on the command line, C# by default writes /t:exe for you thereby creating an executable file. The long form of /t is /target and depending upon the time of day, choose the appropriate one. Not all options have a long and a short form like /t does. The : after the option is mandatory. Then we write the type of executable output file we want. Library means a dll. When we run the dir command we see a file named a.dll in the current sub directory. A file with a .dll or a .exe extension are called Windows PE files. This is the default file format that Windows uses to create executable files. There is a minor difference between the internal structures of a dll and a exe file. Which is that a dll cannot be executed like an exe program can. By convention dlls' are used to store code even though an exe could have also be used. What we have done is created a component. What if we wanted to change the name of the output file. By default it is the name of our program. Then we must use the /out option as follows.
csc /t:library /out:bbb.dll a.cs

This will create a file bbb.dll instead of a.dll as earlier. Whether we use the /out option or not, C# does it for us. If the C# program was called a.cs, then C# wrote /out:a.exe on the command line for us. We can use the /out option to change the name of the output file. /out does not have a short form /o. Remember C# uses defaults for command line options to make life easier for us. Note that we have created a component in a file bbb.dll
a.cs class yyy { public static void Main() {

zzz a; } } Compiler error a.cs(5,1): error CS0246: The type or namespace name 'zzz' could not be found (are you missing a using directive or an assembly reference?)

The only reason we create a component is to allow other programs to call code from it. In the above program, we are saying that a looks like a class zzz. The C# compiler is telling us in a vague way that it does not know that zzz is a class. Though we know zzz is a class as we just created it and it is in a file called bbb.dll, C# is not aware of the same.
a.cs class yyy { public static void Main() { zzz a; } } >csc a.cs /r:bbb.dll Compiler Warning a.cs(5,5): warning CS0168: The variable 'a' is declared but never used

The /r or reference option tells the C# compiler to look at bbb.dll; in this case for the code of classes it is not aware of. In our case the error disappears as the file bbb.dll contains the code for the class bbb.dll. Thus in future, if the C# compiler ever gives you the above error, do not panic. All that you need to do is specify which dll contains the code for the classes. The help available along with C#, tells you every class and the dll that contains the code of the class.
a.cs class yyy { public static void Main() { zzz a = new zzz(); a.abc(); } } Output zzz abc

We have successfully called the function abc in class zzz. The code of the class zzz resides in bbb.dll.
a.cs namespace mukhi { public class zzz { public void abc() { System.Console.WriteLine("zzz abc"); } } } >csc /t:library /out:bbb.dll a.cs

The same class zzz is now enclosed in a namespace mukhi and the component recreated.
a.cs class yyy { public static void Main() { zzz a = new zzz(); a.abc(); } } csc a.cs /r:bbb.dll Compiler Error a.cs(5,1): error CS0246: The type or namespace name 'zzz' could not be found (are you missing a using directive or an assembly reference?) a.cs(6,1): error CS0246: The type or namespace name 'a' could not be found (are you missing a using directive or an assembly reference?)

The error results as the name of the class is not zzz but mukhi.zzz.
a.cs using mukhi; class yyy { public static void Main() { zzz a = new zzz(); a.abc(); } } Output zzz abc

All's well that ends well.

Databases
Databases are centralized stores of data. In a database, information from several files (also known as tables) is accessed, coordinated and operated upon as if in a single file. Thus, the database organizes data independently from the programs that access it. Large volumes of data are stored in a database. Computer programs have little meaning when written in isolation. Therefore, it is of importance to have our programs work with databases. Databases work under the control of a database management system. SQL Server is an RDBMS; it is one such database management system. Before we can write programs that communicate with databases we need to have a database. One of the simplest databases to use is Microsoft Access. As a large number of people use it, we have based our examples on it. However you could use any RDBMS like Oracle, SQL Server as you wish. First and foremost, before we can access a database and perform various operations, we need to connect to the database. Assuming you want to speak to your friend over the phone, you dial your friend's phone number. Its only when you connect to your friends phone that the both of you can speak to each other. Similarly, if we want to use a database we first have to connect to it and only then can we speak to it.
a.cs

class zzz { public static void Main() { System.Data.OleDb.OleDbConnection s; }} Compiler warning a.cs(5,35): warning CS0168: The variable 's' is declared but never used

Let's see how we can connect to a database.


a.cs class zzz { public static void Main() { try { System.Data.OleDb.OleDbConnection s; s = new System.Data.OleDb.OleDbConnection(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output hell

Within the try block we have an object s that looks like System.Data.OleDb.OleDbConnection. You are already aware that System is a namespace, but what about Data and OleDb? Well, System.Data.OleDb is the name of the namespace. We can liken this to an earlier example where we created a namespace mukhi.vijay. Hierarchy in a namespace can go to absurd lengths! The help on C# states that System.Data.OleDb is the name of a namespace and OleDbConnection is a class within that namespace. By saying s = System.Data.OleDb.OleDbConnection(); we are creating the object s. When you run this program all that we see is the word hell, which means that the constructor threw no Exception. If it did then the catch block would have been executed.

a.cs class zzz { public static void Main() { try { System.Data.OleDb.OleDbConnection s; s = new System.Data.OleDb.OleDbConnection(); s.Open(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } }

} Output System.InvalidOperationException: The ConnectionString property has not been initialized. at System.Data.OleDb.OleDbConnection.Open() at zzz.Main()

The class OleDbConnection has a function called Open which opens or connects to our database. When we run the above the above program, the Open function throws an exception. Now, at this point you must catch the Exception. The ToString within the catch block displays the Exception message. The error says that the ConnectionString property has not been initialized. The reason an exception occurred is that we did not provide certain mandatory information whilst creating the object. We did not indicate the location of the database server that we want to connect to or the database. It's like picking up the phone and not dialing a number. How in the world do you expect to connect then! We will now provide the constructor with some basic information.
a.cs class zzz { public static void Main() { try { System.Data.OleDb.OleDbConnection s; s = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb;"); s.Open(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output System.Data.OleDb.OleDbException: Could not find file 'c:\zzz.mdb'. at System.Data.OleDb.OleDbConnection.ProcessResults(Int32 hr) at System.Data.OleDb.OleDbConnection.InitializeProvider() at System.Data.OleDb.OleDbConnection.Open() at zzz.Main()

We first specify the database provider as Provider=Microsoft.Jet.OLEDB.4.0, which stands for MSAccess and then the path as Data Source=c:\\zzz.mdb separated by semicolon. When you run the program, an OleDbException is thrown, which says could not find file 'c:\zzz.mdb'. This is because we have not created an MSAccess DataBase called zzz.mdb. An mdb file stores data from multiple tables. In this file zzz.mdb, create one table abc with 2 fields f1 and f2 , both of type text. Add two records to this database. The first record will contain 1,a1 and the second record will be 2,a2. Re run the program which now displays hell unlike before where we generated an Exception.

Output hell

s.Open opens a connection to the database. The 'Provider' and 'Data Source' given in the constructor identify the database. As we have given the constructor all the mandatory information, s.Open() will open a connection with the Access database. The program executes smoothly and once the connection is established WriteLine displays 'hell'. Now that we have established a connection with the database, let's see how we can communicate with it. More specifically, let's see how we can execute an SQL command.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("Create Table a1 ( vno integer , name char(10))",s); c.ExecuteNonQuery(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output hell

Employing using, we do not have to preface every class with the namespace System.Data.OleDb. The purpose of this program is to execute an SQL statement. SQL is a short form for Structured Query Language. It is not a computer programming language like C# but rather a language like English. SQL understands certain words like Create, which create a table for us in our database. SQL has nothing to do with Oracle or Access, it works with all the RDBMSs of the world.
Create Table a1 (vno integer, name char(10))

The above SQL statement means that a table called a1 will be created in our database. It will have 2 fields vno and name. Vno will store numbers and name will store characters subject to a maximum of 10. A class in any programming language is made up of a collection of variables and functions. These put together do something for us like solving a particular problem or accomplishing a certain task. We live in a world of specialization. Just like it is difficult to come across one human being who is a PHD in Nuclear Science as well as Sociology, classes too are written to focus on one particular task only.

Thus we need one class to handle our connection to a database and another class which understands SQL. We first create an object that looks like an OleDbConnection, which understands how to connect to a database using a string attributes 'Provider' and 'Data Source', which it passes as a parameter to the constructor. Then we create an object c which looks like OleDbCommand as this class understands SQL. The constructor gets called with 2 parameters, the SQL statement and also the connection object. Thus the object c now comprises the necessary information regarding the command we want to execute and the connection. Now, c.ExecuteNonQuery() will actually execute the SQL statement. ExecuteNonQuery() is a function within the OleDbCommand class that enables us to execute any SQL command. You will now see the word 'hell' displayed on your screen. But did the table get created? Let's find out by starting Access and then choosing the database zzz. Here we will see the table a1 with 2 fields vno and name but with no data at all. We created our table alright, but it is empty as it has no data in it! So let's start inserting data/records into the table. Before doing so, Quit out of Access
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("insert into a1 values(1,'hi')",s); c.ExecuteNonQuery(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } }} Output hell

The only difference between this program and the previous one is that this one uses the Insert SQL command. Earlier, we created a table zzz, now we are inserting records in zzz. To the constructor of OleDbCommand we are giving two things - the insert command "insert into a1 values(1,'hi')" and the connection. Insert into and values are part of the SQL syntax. A1 is the name of the table in which a fresh record will be added. After values, we write the data separated by commas. The first field will contain 1 and the second hi. As the second field has the data type of character, it has to be enclosed in single quotes. c.ExecuteNonQuery as usual executes the SQL command and as no exception gets thrown ,the word 'hell' gets displayed.. Let's cross check to see if the data has been inserted into zzz by running Access. Aha! It displays the record that you just inserted in the following formatvno name 1 hi Now it follows that if we can insert a record then we should be able to remove it too. The following program uses the delete command to remove all the records from the table zzz.
a.cs

using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("delete from a1",s); c.ExecuteNonQuery(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output hell

Now c.ExecuteNonQuery will execute the delete command. This command deletes all the data from the table. In Access we will see an empty table. This proves that the delete command was successful! Apart from inserting and deleting data another operation that is commonly performed is updating data. However, you must have data in your table to update it. Our table is empty right now, so let's execute the insert program once again. You will now have one record in your table zzz. After inserting a record, change the sql insert command to an update command. This is shown below.
c= new OleDbCommand("update a1 set vno=3,name='bad' where vno=1",s);

Here, we are giving an update statement and our connection to the object is 'c'. The update statement will change the vno and name to the values specified. It will do so for any record that has vno=1. We have only one record in our table and it meets this criteria. Now, go back to Access , you will find that the record has been updated as followsvno name 3 bad
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("delete from a11",s); c.ExecuteNonQuery();

System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output System.Data.OleDb.OleDbException: The Microsoft Jet database engine cannot find the input table or query 'a11'. Make sure it exists and that its name is spelled correctly. at System.Data.OleDb.OleDbCommand.ExecuteCommand TextErrorHandling(Int32 hr) at System.Data.OleDb.OleDbCommand.ExecuteCommand TextForSingleResult(tagDBPARAMS dbParams, Object& executeResult) at System.Data.OleDb.OleDbCommand. ExecuteCommandText(Object& executeResult) at System.Data.OleDb.OleDbCommand. ExecuteCommand(CommandBehavior behavior, Object& executeResult) at System.Data.OleDb.OleDbCommand. ExecuteReaderInternal(CommandBehavior behavior, String method) at System.Data.OleDb.OleDbCommand.ExecuteNonQuery() at zzz.Main()

Don't worry, we have simulated this error on purpose. The table a11 does not exist in our database. Thus an exception got thrown by ExecuteCommandText and not ExecuteNonQuery as seen above. What it means is that ExecuteNonQuery calls Execute which calls ExecuteCommand which finally calls ExecuteCommandText. Also the word hell does not get displayed because of the exception thrown. We will now execute a simple select statement.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output hell

We have executed different SQL commands through our earlier programs. We will now try and execute an SQL select statement. In order to do so, we have given the following select statement to the constructor along with the connection- 'Select * from abc'. Abc is a table in the database called zzz . Remember, c looks like OleDbCommand. 'Select' is part of the SQL syntax like insert , update . 'from' is also a reserved word . 'abc' is the name of the table created earlier in Access and populated by data keyed in by us. The '*' means all fields in the table. We could have also replaced the * with a comma separating list of field names that we were interested in. As OleDbConnection has an Open function, OleDbCommand has a ExecuteReader function. This function returns an object that looks like OleDbDataReader. The function ExecuteReader will create an object that looks like OleDbDataReader and initialize r to it. No exception was thrown, which meant no errors from our side. What we need to do now is retrieve data from the abc table. The abc table may have ten fields and twenty records. So we use what is called a 'dataset'. In other words, how do we access data contained in multiple rows and multiple columns through our program? For example, when we run the select statement it gives us the data in rows and columns. How can we achieve this through our program? To do that we now need a third object which looks like OleDbDataReader. We can almost feel your dismay - Oh no! Another object! Well, there is a very good reason why you need to have three different objects. Firstly, you need an object that understands a connection. Then you need another object that understands an SQL statement. This is because somebody has to execute that statement. You now need a third object that will let you read/retrieve data. That is why we have 'r' an object that looks like OleDbDataReader. Thereafter, we have c.ExecuteReader. Earlier we used a function call ExecuteNonQuery. This is because in case of an insert, update or delete we didn't want any data to be retrieved, we didn't want an answer back!! As a recap, we are using r to store the value return by ExecuteReader. That means r will be filled up by ExecuteReader. On executing this program only 'hell' is displayed. Now that we have the filled up r, let's see how we can display the data.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine("{0},{1}",r.GetValue(0),r.GetValue(1)); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } }

} Output System.InvalidOperationException: No data exists for the row/column. at System.Data.OleDb.OleDbDataReader.DoValueCheck(Int32 ordinal) at System.Data.OleDb.OleDbDataReader.GetValue(Int32 ordinal) at zzz.Main()

Run this program. Expect the unexpected....an error! The error says 'No data exists for the row/column' But didn't the function Execute fill up r? It did, but it did not position the record pointer on the first record. A record pointer is an abstract concept. To start with it appears just before the first record. The function GetValue will return the value of the fields depending upon where the record pointer is. At the start it is just before the first record. So r can be also looked at as an array that contains all the fields. We get an error because we need to read the data into our array first. In order to read data into the fields we must give r.Read. Without r.Read, the records will not be read into the array, so also the record pointer will not be moved forward to the first record. Now that we know the reason why the error occurred let's rectify it by doing the needful. Let's add r.Read() to our program.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine(r.Read()); System.Console.WriteLine("{0},{1}",r.GetValue(0),r.GetValue(1)); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output True 1,a1

Now that we have added r.Read() the program executes as advertised. r.Read() returns true. Thereafter, the GetValue() function which needs the field number as a parameter retrieves the data associated with the first and second column. Remember in C# we start counting from zero and hence zero as a parameter to GetValue will retrieve the value of field one in the table. The datatype of the first field is numeric and of the second character. However, the function GetValue does not seem to care. Read returns true if more data is available to read and false if it is at the last record. Also read positions the record pointer to the next record.

a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); while (r.Read()) System.Console.WriteLine("{0},{1}",r.GetValue(0),r.GetValue(1)); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output 1,a1 2,a2

(A display of only the first two fields of all the records in the table. ) But now we want to display all the data in the fields. So we are using Read in a loop. while(r.Read()). r.Read() returns true as long as it can read data. The while loop continues till the condition is true. We are using our trusted function WriteLine to display the data of the first and second field. Thus the moment r.Read() cannot read more data it returns false and the while loop terminates. Now all the data in the two fields is displayed and as such we have a long list of data displayed. To verify further, add some more fields and records to abc. Just as we mind our manners in daily life we must do so in programming too. It is a good practice to shut the door when leaving a room. Similarly, in programs we must close what ever we opened.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); while (r.Read())

System.Console.WriteLine("{0},{1}",r.GetValue(0),r.GetValue(1)); r.Close(); s.Close(); System.Console.WriteLine("hell"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output 1,a1 2,a2

We will mind our manners and give r.Close() and s.Close. Note that it is not mandatory to do so. First we are closing r and then we are closing s i.e. the connection that we opened.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine(r.FieldCount); for ( int i = 0 ; i < r.FieldCount ; i++) System.Console.WriteLine(r.GetName(i)); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output 2 f1 f2

An OleDbDataReader has a useful function called FieldCount which tells you how many fields the SQL statement contained. In our case abc has two fields. We have one more function GetName which will tell us the name of the function in the table given the field number. Thus r.GetName(1) will give us the name of the 2nd field. In the for statement, the variable i starts at zero. The condition becomes false when the value of i is one less than r.FieldCount which in this case is 2 i.e. i will take values of 0 and 1. The reason being i starts from zero as GetName understands zero as the first field. Thus we can now print all the column names using the for. Now lets print the entire table irrespective of the number of columns or the number of rows.

a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); while ( r.Read() ) { for ( int i = 0 ; i < r.FieldCount ; i++) System.Console.Write(r.GetValue(i)+" "); System.Console.WriteLine(); } } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output 1 a1 2 a2 You can modify abc to add more fields and fill in more records. Execute the program and see the change in output. Whenever we do not know better, we use a for or a while i.e. a looping construct. However we do not know two things. One, the numbers of rows in the table and two the number of columns. The first while takes care of the number of rows and the for, the variable number of columns. Thus the above program will work for any number of columns and rows in the table. All that we do is change the select statement. The difference between Write and WriteLine is that Write does not add an enter at the end like WriteLine does. Also + is used to join two strings together. We are adding a space at the end of every field as a separator.

Web Enabling Data


We now have to our credit, programs that enable execution of a general purpose select statement as well as those that update, insert and delete commands. These were all C# programs which were compiled into executable files. Let's assume you want to display the contents of the customer table. Our program will very well serve this purpose. Alternatively, the program can be made to accept user input and depending upon the table name that the user typed in, the program can display contents of that table. You can easily do so with the help of a function called GetLine in Console. GetLine will cause the program to wait at the console for the user input followed by the 'Enter' key. This situation comes with its share of problems though. The problem is that if there are five people who are going to use this program then you need to give them five copies of the program. If there are five thousand such users then you have to copy this on to five thousand different machines. Simply not possible. Wait a minute! Did you get a sudden brainwave? The perfect solution would be to 'put it on a network'!! But don't forget that there are many networking standards available. Some may have Novell, some may have Windows 2000, and others may have the Macintosh or even Linux/Unix. So what do we do now? You will have to make sure that the same program works under Linux as well as it does under a Mac or any other standard. Apart from this you would have the headache of having to train people to use the program. The only solution to this problem is Web enabling data. This is the new standard of writing code. You need to access your data using Internet Technologies. It's only then that we can eliminate the loopholes that exist within the already available standards. No matter which operating system you install, along with it you get access to a browser. When you use the Internet you use a browser, a.k.a. an user agent, that enables you to view web pages and enables data transfer over the Internet. Since we do have a browser, can't we do a simple thing? Let the user type the name of our machine and get a form. Within the form he can key in the table name and once he does that he will get the details of that table. Which means you will now have to execute your code on a program called the WebServer. This is what is meant by Web Enabling Data. But before we leapfrog into the world of Web Enabling Data, let's acquaint ourselves with the basic language that the browser understands. It is called HTML.

HTML
Amongst browsers, the usual suspects are Netscape Navigator and Internet Explorer. What happens when you view a web page using such a browser? Technically speaking, you connect to a web server and a file comes over onto your computer, which is generally an HTML file. HTML is the acronym for Hyper Text Markup Language. It is a document-formatting language. HTML is basically a stream of characters without any intelligent functionalities like the for and if statements. Hence it cannot be considered an equivalent of a programming language. HTML, as simple as it is, allows any bumpkin to be an ace at it! Assuming you have a Web Browser, let's write our first HTML program. You can use any editor like word to type your program in. The only thing that you must bear in mind is that the file must be saved with the extension .htm or .html. Create the file in your root directory. In our case, we will save in c: and since we are using the dos editor we shall begin by saying edit a.html

C:>edit a.html

Type the code as we have done below.


a.html Hi Bye Output Hi Bye

Note that the text must be on two separate lines. Once you have saved your file run your browser. In the browser you will see a white text box known as the address bar. Click there and type c:/a.html, in our case we have saved the file in the root of the C drive. As of now we are picking up this html file from our hard disk. But when you are on the Net you are accessing a file from some other machine on the net. In that case, you give the address of that machine. For instance, if you want to connect to the Microsoft site, you will type www.microsoft.com. Apart from that there is no difference in trying this on the Net or off the Net. When the browser sees an html file, it reads it line by line. Hence, in the browser window you will see Hi Bye displayed. Wow! You have just written your first html program! But didn't we write Hi and Bye on two separate lines? The browser, dumb as it is doesn't seem to understand this. Looks like the browser, by default, ignores enters! So, how can we make the browser understand? We can do so with the help of 'tags'. HTML is based on 'tags', which instruct the browser how to display a piece of text or an image/picture. A tag begins with '<' and ends with '>'. So let's add a tag.
a.html Hi <br> Bye Output Hi Bye

Going by the definition of a tag you will realize that br is a tag. It is enclosed within the angular brackets. <br> means next line. Save the file. Now when you view this file in the browser you will find that Hi and Bye are displayed on two separate lines. Hence, HTML is nothing but a collection of tags. You just need to know which tag satisfies what purpose.
a.html <b> Hi </b> <br> Bye Output Hi Bye

In this program, the tag b means bold. But here we also have </b>, which is a closing tag. This indicates that we are closing the <b> tag. Whatever is enclosed between the two will be made bold. Hence only Hi

will be bold. HTML tags are romantic, most of them always travel in pairs - called an opening tag and a closing tag. But some tags like <br> like to play the field for they prefer to remain single. Using the <i> tag we will display Hi in italics.
a.html <i> Hi </i> <br> Bye Output Hi Bye

It is all very mechanical! <i> means italics and hence Hi is displayed in italics. Had you included bye within <i> and </i> then bye would be in italics too! That's all the understanding that is required to learn HTML! Now we have included another tag <h1>
a.html <i> Hi </i> <br> <b> Bye </b> <br> <h1> You are Welcome again! <h1> Output Hi Bye You are Welcome again!

Since Hi is included in <i> </i> it will be displayed in italics. Bye is displayed in bold due to the <b> tag. <hi> means heading1, it makes the text bigger. Thus, 'You are Welcome again!' is displayed in a bigger font.

a.html <html> <body> <i> Hi </i> <br> <b> Bye </b> <br> <h1> You are Welcome again! <h1> </body> </html> Output Hi Bye You are Welcome again!

This program outputs the same result as the above. The only difference is that now it is a well-formed HTML program. Every HTML file must begin with the <html> and end with </html> tag. Whatever text is to be displayed within the browser must be enclosed within the <body> and </body> tag. This is the way an HTML program must be written. Hope the purists have forgiven us now! Let's make our page attractive by adding a picture to it. Copy any gif file to your root directory and name it aa.gif. In our case, we copied it to c:

a.html <html> <body> <i> Hi </i> <br> <b> Bye </b> <br> <img src="aa.gif"> <h1> You are Welcome again! <h1> </body> </html>

img is the image tag, it is used to display pictures. Along with this tag you have to specify the name of the image file. Following the word 'img' is the word 'src' and after the '=' sign you specify your filename. i.e. aa.gif. You can give the name of any picture file. But follow this syntax! Another thing to note is that you can have the file name included in single quotes or double quotes or you may exclude them totally. Thus viewing this file in the browser will now display the image you specified along with the text. In HTML parlance, src is called an attribute. An attribute describes / qualifies a tag.
<a href=a.html> Hi </a> <a href=b.html> Bye </a>

You will see two hyperlinks in your browser window. The names of the html files will not be displayed but the words Hi and Bye will be underlined. And if you click on hi and bye the respective html files will be displayed instead. Then there are tables in HTML
a.html <html> <table border=10> <tr> <td>hi</td><td>100</td> </tr> <tr> <td>1000</td><td>bye</td> </tr> </table> </html>

The table tag has one attribute, border, that specifies how the lines or borders between columns looks like. The table tag encompasses two tags . tr stands for a table row and td for a table columns. We have two tr's , hence we have two rows and each tr encloses two td's one for each column. Similarly, you can keep adding more and more tags depending on how you want your page to be displayed. Any book on HTML will list all the available tags. Our aim is not to learn html here but to use C# on the Net. Since knowing this much will suffice our forthcoming needs, let's get back on track!

Using C# on the Net


Now that you are familiar with the rudimentary elements of HTML, let's see how we can apply our recently acquired knowledge in conjunction with C# on the Net. First and foremost you need a Web Server. Hence you will now need to install Apache. You can download Apache from http://www.apache.org and then run the installer program. Among the Apache directories, there are two sub-directories that are of importance to us, namely, cgi-bin and htdocs. The cgi-bin sub-directory is used for storing executable files.

In order to change to the cgi-bin sub-directory follow the path as given below.
C:\progra~1\apache~1\apache\cgi-bin

And to change to the htdocs sub-directory give the following path.


C:\progra~1\apache~1\apache\htdocs

The htdocs sub-directory is used for storing html files. To install the Apache Web Server all that you need to do is download the install program on your hard disk. Run the executable program which will install apache in the apache group directory of program files. Change to C:\progra~1\apache~1\apache directory and then run the web server as follows.
C:\progra~1\apache~1\apache >apache

If you get an error about some server name, cd to the conf sub directory , edit a file called httpd.conf , change a line starting with #ServerName to ServerName localhost and all should be well after that. Now that you have the Apache server running, activate your web browser. Type the address 127.0.0.1 in the address bar and press enter. Every machine on the internet is known by a number. We call this number an IP address. IP stands for the Internet Protocol. Every machine that has the Internet software running is also known by the number 127.0.0.1 or localhost. In case a file called index.html exists, the browser will display it. This is because it is located in htdocs and is the file that gets picked up by default when you give your machine address and you have Apache running. Change to the htdocs sub-directory and create an html file a.html to display a form.
a.html <html> <form> <input type=submit value=Search> <form> </html>

The <form> tag is used to specify that we are creating a form. <input type=submit is the syntax for creating a button. Value =Search means that 'Search' is the word that will appear on the button. Had we said Value = Vijay, you would see the 'vijay' on the button. Save the file as a.html in the htdocs subdirectory. Go to the browser window and type http://127.0.0.1/a.html in the address bar and press enter. You will now see a button with the name Search on it. But clicking on this button doesn't serve any purpose as of now. Let's alter the program such that when the user clicks on the Search button our C# program should execute. So first we will write our C# program.
C:\csharp>edit a.cs

Now type the following code.


a.cs class zzz { public static void Main() {

System.Console.WriteLine("hi<b>bye"); } } Output hi<b>bye

This is a simple program that should display hi and bye. Save the program as a.cs. On compiling the program an executable file 'a' is created. If you run the program as we have been doing, you will see the output as given above. But remember, what we just told you about executables? When you are using Apache you must save all executables in the cgi-bin sub-directory as a security precaution. Hence you must copy a.exe to cgi-bin by giving the following command.
C:\csharp>copy a.exe c:\progra~1\apache~1\apache\cgi-bin

Now we will alter our HTML program. Within the form tag include action=http://127.0.0.1/cgi-bin/a.exe This indicates the action to be performed when the button is clicked. Since we want our program a.exe to run, we have given its path.
a.html <html> <form action=http://127.0.0.1/cgi-bin/a.exe> <input type=submit value=Search> <form> </html>

Now that we have everything ready, let's get on with the show! Activate your browser and type http://127.0.0.1/a.html in the address bar. You see the button labeled Search. Now click on this button. To your horror you see an error! The browser window displays an Internal Server Error. Note the url in the address bar- http://127.0.0.1/cgi-bin/a.exe? Now make the changes as we have done below.
a.cs class zzz { public static void Main() { System.Console.WriteLine("Content-Type:text/html\n"); System.Console.WriteLine("hi<b>bye"); } } Output in Browser hibye

Save your file, compile it and again copy it to cgi-bin once again. Now when you run your program from the browser, the error vanishes! And you will see hi bye displayed. That means it is mandatory to give Content-Type. It tells the browser that what is being sent across is a text file. Also the content is qualified as html and not pure text. It is also called a header. Because we are saying html, the bye is displayed in bold. So we created a file and the file goes over i.e. what ever is in Console.WriteLine goes over. Now remove html and instead write plain. Let's see what happens. After making the necessary changes and compiling the program copy it again to cgi-bin.
a.cs

class zzz { public static void Main() { System.Console.WriteLine("Content-Type:text/plain\n"); System.Console.WriteLine("hi<b>bye"); } } Output in Browser hi<b>bye

Now run your program from the browser. You will notice that bye is not displayed in bold. Also note that now the tags are displayed as normal text. They show no formatting effects. This is because instead of the word html we are now saying plain. That means the browser will now display everything as plain text. Thus the Content-Type: header is used to indicate to the browser that we are sending text followed by HTML. Thus if we want our program to execute on the web it is mandatory that we include this header in our program as the web server does not know what is the file type it is sending over. Now that we have all the ingredients for the final show, let's get on with it. We will now add the header to our general-purpose select program. We will do this so that we can display the contents of a table on the web. Thus the only change that we have made to the program is to add the following line:
System.Console.WriteLine("Content-Type:text/html\n"); a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand("select * from abc",s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine("Content-Type:text/html\n"); while ( r.Read() ) { for ( int i = 0 ; i < r.FieldCount ; i++) System.Console.Write(r.GetValue(i)+" "); System.Console.WriteLine(<br>); } } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } }

We have also added System.Console.WriteLine("<br>"); so that each record is displayed on a new line. The browser will see <br> and understand it as an html tag. This is because in the header we have specified text/html. As such you will see each record on a new line. Now save the file and compile it. Copy the file a.exe to the cgi-bin sub-directory. Activate the browser window and type http://127.0.0.1/a.html in the address bar. Now click on the search button. Accolades! You have successfully run your C# program from the browser. You will now see all the contents of the abc table. Why the abc table? Because that's the table you specified in your program. Thus, whenever the user clicks on the button in the browser he is calling a program on the server. The server could be a trillion miles away!! However, even now everything is not hunky dory. The major problem being that this entire approach is inflexible. Earlier, we told you we need this type of programming because we didn't want to copy the programs on each machine. But the problem with the Web Server is that if it contains ten html files then we can give the user only those ten html files. So we are only giving him ten views. However, what we really need to do is that we need to pass data from us to his machine. For example, let's assume we have a database that has names of people. We should have a form in which the user can write the name of a person. When he clicks on 'ok' that name should get added to the database. In effect, we are adding one persons data to the database. Similarly, we should be able to delete a person from the database too. And finally we can have a table-display program wherein the user will provide the table name. When he clicks on ok, the contents of that table will be displayed. Thus you can now think of generating flexible programs. You probably felt limited earlier as you could display contents of only that table whose name you had provided within the program.

Environmental Variables
Before we get down to making our programs flexible we need to understand as to how we can deal with Environmental Variables in C#. An Environmental Variable is a word that the operating system understands.
a.cs class zzz { public static void Main(){ string s; System.Console.WriteLine("Content-Type:text/html\n"); s=System.Environment.GetEnvironmentVariable("PATH"); System.Console.WriteLine(s); } } Output Content-Type:text/html C:\JDK1.2.2\BIN; C:\WINDOWS\MICROSOFT.NET\FRAMEWORK\V1.0.2204\; C:\WINDOWS; C:\WINDOWS\COMMAND; C:\BORLANDC\BIN; C:\WINDOWS; C:\WINDOWS\COMMAND; C:\PROGRAM FILES\MTS

Displays the value of environmental variable called PATH. An environmental variable is a word, which stores a value. When you give the command set xyz=bye at the command prompt, xyz becomes an environmental variable, which stores the value bye. All operating systems allow you to create environmental variables . The environmental variable PATH stores a list of directories that the operating system searches for to find executables files. Run it off the web server or by itself.
a.cs class zzz

{ public static void Main(){ System.Collections.IDictionary i; i=System.Environment.GetEnvironmentVariables (); System.Collections.IDictionaryEnumerator d; d=i.GetEnumerator(); System.Console.WriteLine("Content-Type:text/html\n"); System.Console.WriteLine(i.Count + "<br>"); while (d.MoveNext()) { System.Console.WriteLine("{0}={1}<br>",d.Key,d.Value); } } }

There can be 100's of environmental variables and we would like a list of all of them. The class Environment in the System namespace has a function GetEnvironmentVariables which returns an object that looks like IDictionary. This IDictionary object has a function called GetEnumerator which returns an object that looks like IDictionaryEnumerator. You have to learn all this by rote, there is no other option available. We are then displaying how many environmental variables there are by printing a member Count in IDictionary. Then we need to activate each variable by calling MoveNext which returns true if there are more environmental variables in the list. An environmental variable is represented by a key-value pair, which is also variable in the IDictionaryEnumerator class. Thus we can display all the environmental variables starting with a count of how many there are. If you check the list of environmental variables in your browser, you will see one called QUERY_STRING , but it will have no value. Now run as http://127.0.0.1/cgi-bin/a.exe?aa=ho and see the variable QUERY_STRING have a value aa=ho.
a.html <html> <form action=http://127.0.0.1/cgi-bin/a.exe> <input type=submit value=Search> <input type=text name=aa> <form> </html>

Run the file in the browser. And you will now see a text box which is internally called aa. This is because of the tag input type=text. Type ho in the text box and click on search. The URL will now change to http://127.0.0.1/cgi-bin/a.exe?aa=ho and the variable QUERY_STRING will have the value aa=ho.
a.html <html> <form action= http://127.0.0.1/cgi-bin/a.exe > <input type=submit value=Search> <input type=text name=aa> <input type=text name=bb> <form> </html>

Now we will see two text boxes in which we will type in ho and no. Click on Search and the url will change to http://127.0.0.1/cgi-bin/a.exe?aa=ho&bb=no and the variable QUERY_STRING will have the value aa=ho&bb=no.

CGI Programming

Let us now understand what goes on once again. What we have been trying to explain to you is called CGI programming where CGI stands for Common Gateway Interface. Everyone refers to by its acronym rather than its expanded full form. CGI is a means by which a client i.e. a browser can send some information to the web server. Now typically what happens when we land up at a search engine? Well, we want to send the web server i.e. yahoo the words that we want it to search the internet for. At times we are asked to fill up a form on the web asking for some personal details. The information we key in is sent across to the web server. Lets start with the above HTML file that makes CGI happen. We have two input tags which have an attribute type=text. Thus we see two text boxes on our screen. We will type in them hi and bye respectively. The third input tag has a type=submit and another attribute value=search. This makes it into a button with the word search written on it. Now, when we click on search after typing in data in the text boxes, the browser knows that you have clicked on a button of type submit. So, it will now look for a tag form , and when it finds it , it will read the attribute action. Whatever is the value of action, it will write it in the address bar. In the address bar we write a URL or Uniform Resource Locator or the address of a computer on the net. In our specific case, our browser's address bar will contain http://127.0.0.1/cgi-bin/a.exe. The browser does not stop here. It then adds a ? to the end of the above URL . Now it looks at every text box that we have in the form. The first one has been given a name aa and we type hi in it. So our URL now changes to http://127.0.0.1/cgi-bin/a.exe?aa=hi. It's not over yet as we have one more text box to finish with. This one is called bb and has bye in it. Thus our URL now reads http://127.0.0.1/cgi-bin/a.exe?aa=hi&bb=bye. The & is used to separate different parameters. aa and bb are also called parameters. This url is sent across to the web server. The web server is just another name for a file server. It can only send files across. In this case we are asking it to run a program called a.exe from the cgi-bin sub directory. Before the web server runs a.exe, it creates one environmental variable called QUERY_STRING and initializes it to whatever follows the ? i.e. in this case aa=hi&bb=bye. The web server now runs a.exe. What a.exe actually does is none of its concern. All that is wants from a.exe is a html file which the web server sends back to the browser. The web server also needs at least one header Content-Type which tells it the type of file being sent across. Normally a.exe would read the environmental variable QUERY_STRING, extract the parameters, then read a database, extract some values from it and finally create an HTML file which it would hand over to the web server. All in all, this is how the magic of the internet is bought about. Now, let's learn some more C#.
a.cs class zzz { public static void Main(){ string s ; string [] e; char[] c ; s = "hi=bye&no=bad" ; c = new char[2]; c[0] = '&'; c[1] = '='; e = s.Split(c); foreach ( string t in e) System.Console.WriteLine(t); } } Output

hi bye no bad

s is a string which has been initialized to hi=bye&no=bad which looks similar to what QUERY_STRING as explained earlier looks like. C is an array of chars which has two members initialized to & and = respectively. The string class has a member Split, which will split a string as per the delimiters provided as the first parameters in an array of chars. Thus the split function will take the string s and split it whenever it sees a & or a = . In this case it will result in 4 strings. Split returns an array of strings which we are storing in an array e and using foreach to display the array. Now lets us create a simple form based web application which will accept a table name and then display the entire table for us. The html file a.html as usual will be copied to the htdocs sub-directory.
a.html <html> <form action= http://127.0.0.1/cgi-bin/a.exe > <b> Enter Table Name </b> <input type=text name=aa> <p> <input type=submit value="Show Table"> <form> </html>

We will run as:


http://127.0.0.1/a.html

Our C# program freshly compiled and copied to the cgi-bin subdirectory would now read as:
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { string t; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); string [] u; char [] v = new char[1]; v[0] = '='; u = t.Split(v); string w; w = "select * from " + u[1]; OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand(w,s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine("Content-Type:text/html\n"); while ( r.Read() ) {

for ( int i = 0 ; i < r.FieldCount ; i++) System.Console.Write(r.GetValue(i)+" "); System.Console.WriteLine("<br>"); } } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } }

At our web form we are asked to write the name of the table. Then click on the button Show Table. The web browser now writes the following URL in the address bar after we wrote abc as the name of our table. http://127.0.0.1/cgi-bin/a.exe?aa=abc. The Apache Web Server now runs a.exe. a.exe is nearly similar to what we wrote earlier with some minor modifications. t contains the value of the environmental variable QUERY_STRING . v is an array of chars with one member which is our delimiter '='. Split will return an array of strings in u , in our case aa and abc which will be stored in u[0] and u[1]. Earlier we hard-coded the SQL Select statement. Here w starts with the constant string 'Select * from ' and the name of the table is got from u[1] which in turn gets its value from the environmental variable QUERY_STRING. Write the name of any table that exists in the database in the text box and see how you have been able to web enable your data on the net. Lets use the table tags to make our data look more appealing in the browser.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { string t; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); string [] u; char [] v = new char[1]; v[0] = '='; u = t.Split(v); string w; w = "select * from " + u[1]; OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand(w,s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine("Content-Type:text/html\n"); System.Console.WriteLine("<table border=10>"); while ( r.Read() ) { System.Console.WriteLine("<tr>"); for ( int i = 0 ; i < r.FieldCount ; i++) { System.Console.Write("<td>" + r.GetValue(i) + "</td>"); } System.Console.WriteLine("</tr>"); }

System.Console.WriteLine("</table>"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } }

The output looks great. We have made very small additions to our program, mostly cosmetic. We start with the table tag with a border. The while gets called once for every record and in this while we start and end with a row tag tr and /tr. The for gets called for every field and here we enclose the field value with a tag td and /td. At the end of the while we end with the /table tag. The only problem is that we have not displayed the field names at all. Let the next program do so.
a.cs using System.Data.OleDb; class zzz { public static void Main() { try { string t; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); string [] u; char [] v = new char[1]; v[0] = '='; u = t.Split(v); string w; w = "select * from " + u[1]; OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; c=new OleDbCommand(w,s); OleDbDataReader r; r = c.ExecuteReader(); System.Console.WriteLine("Content-Type:text/html\n"); System.Console.WriteLine("<table border=10>"); System.Console.WriteLine("<tr>"); for ( int i = 0 ; i < r.FieldCount ; i++) System.Console.WriteLine("<td>" + r.GetName(i) + "</td>"); System.Console.WriteLine("</tr>"); while ( r.Read() ) { System.Console.WriteLine("<tr>"); for ( int i = 0 ; i < r.FieldCount ; i++) { System.Console.Write("<td>" + r.GetValue(i) + "</td>"); } System.Console.WriteLine("</tr>"); } System.Console.WriteLine("</table>"); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } }

All that we did was to copy the for loop which generated the field names from an earlier program. We put a tr and a /tr around the for loop and the names of fields are tagged with td. Great looking output.
a.cs class zzz { public static void Main() { string t; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); System.Console.WriteLine("Content-Type:text/html\n"); System.Console.WriteLine(t); } } Output aa=select+*+from+abc

In the original a.html instead of writing a simple table name we wrote select * from abc instead. When we displayed the environment variable QUERY_STRING we learn that the spaces are replaced with a + sign. The rules of creating a URL specify that a space is a forbidden character and all spaces that we write are replaced by a +. Thus we have to convert the + back into spaces.
a.cs class zzz { public static void Main() { string t,s; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); System.Console.WriteLine("Content-Type:text/html\n"); s = t.Replace('+',' '); System.Console.WriteLine(s + "<br>"); System.Console.WriteLine(t); } } Output aa=select * from abc aa=select+*+from+abc

The string class has a method called replace which replaces every occurrence of the first parameter i.e. + with the second i.e. a space. Thus s is t but with the plus sign replaced by a space. Lets us know write an insert statement which will ask the user to key in his first and last name and then add it into a table. We create a table 'bbb' in our database with two fields f1 and f2 both character type. Our html file also now changes to.
a.html <html> <form action= http://127.0.0.1/cgi-bin/a.exe > <b> Enter Users First Name </b> <input type=text name=aa> <p> <b> Enter Users Last Name </b> <input type=text name=bb> <p> <input type=submit value="Add"> <form>

</html> a.cs using System.Data.OleDb; class zzz { public static void Main() { try { OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c; string t; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); string [] u; char [] v = new char[2]; v[0] = '='; v[1] = '&'; u = t.Split(v); string f1,f2,f3; f1 = u[1].Replace('+',' '); f2 = u[3].Replace('+',' '); f3 = "insert into bbb values('" + f1 + "','" + f2 + "')"; System.Console.WriteLine("Content-Type:text/html\n"); System.Console.WriteLine(f3); c=new OleDbCommand(f3,s); c.ExecuteNonQuery(); } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } } Output insert into bbb values('vijay ram','mukhi') URL in Address Bar. http://127.0.0.1/cgi-bin/a.exe?aa=vijay+ram&bb=mukhi

The first change is that our array of chars is now two members large and the second delimiter is the '&'. Thus our QUERY_STRING will break into 4 strings aa , vijay+ram , bb and mukhi in u[0] to u[3]. We replace the + with the ' ' in both strings and dynamically generate the insert statement. It looks confusing but is not, Once again f1 and f2 contain the dynamic data but because they are strings we need them to be separated by a single inverted comma. Thus the complication in concatenating strings. The browser displays the SQL statement that will be executed, but in real life we would display a success or error message.

Data Search Program


Now let us write a search engine or more precisely, a general purpose data retrieval engine. For which we have to first create a simple database that will contain the following fields : Keyword - that will store what the page contains, url - the address of the page,

name - to be displayed instead of the url and finally the text that will be displayed explaining the page.
create table ss ( keyword char(10), url char(100), name char(100), descrip char(100));

We will also add the following records.


insert insert insert insert into into into into ss ss ss ss values values values values ( ( ( ( 'java', 'a.html', 'java site', 'great java site'); 'c', 'b.html', 'c site', 'great c site'); 'basic', 'c.html', 'basic site', 'great basic site'); 'cobol', 'd.html', 'cobol site', 'great cobol site');

Create the following html files in the htdocs subdirectory


search.html <html> <form action= http://127.0.0.1/cgi-bin/a.exe > <b> Enter keyword </b> <input type=text name=aa> <p> <input type=submit value="Search"> <form> </html> a.html The file is for java b.html The file is for C c.html The file is for Basic d.html The file is for Cobol

The C# program will be as follows


a.cs using System.Data.OleDb; class zzz { public static void Main() { try { string t; t=System.Environment.GetEnvironmentVariable("QUERY_STRING"); string [] u; char [] v = new char[1]; v[0] = '='; u = t.Split(v); string w; System.Console.WriteLine("Content-Type:text/html\n"); w = "select * from ss where keyword='" + u[1] + "'"; OleDbConnection s; s = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\zzz.mdb"); s.Open(); OleDbCommand c;

c=new OleDbCommand(w,s); OleDbDataReader r; r = c.ExecuteReader(); while ( r.Read() ) { System.Console.WriteLine("<a href=/{0}> {1} </a> {2} <br>",r.GetValue(1),r.GetValue(2),r.GetValue(3)); } } catch(System.Exception e) { System.Console.WriteLine(e.ToString()); } } }

Open up the browser and enter the url 'http://127.0.0.1/search.html' All that this program does is use the concept of a hyperlink to build a search engine and extract data from a database. We assume we have a database of a trillion records that map the internet telling us the keywords that each url stands for. The user keys in the name of a language and we use the select statement to fetch the records meeting the condition, format it and then send the html file across. We can use the same concept to fill up a list box. The html tags for list box are as follows
<select name = aa> <option> blue </option> <option> red</option> <option> orange </option> </select> In a real life situation, the colours will be retrieved from a database and the HTML file generated by a CGI program.

6
Miscellaneous Multiple files
A C# program can be spread over multiple files. So far all our code has been written in one large file. Lets us create 2 .cs files a.cs and b.cs as follows

a.cs class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } b.cs public class yyy { public void abc() { System.Console.WriteLine("hi"); } }

Earlier our code did not spawn multiple files. C# does not care whether the code is in one file or spread over multiple files. We have only to make a small change while we compile the program. Running Csc a.cs b.cs will create a.exe
Output Hi

These files are called source files and it is a good idea to give them a file extension of .cs. If you rename b.cs to b.xxx as we did and rerun csc as
>csc a.cs b.xxx

This will create a.exe as usual. File extensions matter to the programmer not to the compiler.

Ascii and Unicode


a.cs class zzz { public static void Main() { System.Console.WriteLine((char)65); System.Console.WriteLine((char)66); System.Console.WriteLine((char)67); } }

Output A B C

Computers in a way are pretty dumb. They do not understand letters of the alphabet. All that they can store in memory are numbers. But then, how does a computer understand or display alphabets? The WriteLine function displays 65 as 65, but the output is A. In the () brackets we have placed a data type

called char. We call a ( ) a cast. It means, for the moment convert whatever follows into a char. Thus the number 65 gets converted into a char which is displayed as a 'A'. The 66 gets displayed as a 'B'. Someone, somewhere in the world invented a rule which specified that the number 65 represents a capital A, etc. This rule is given a name and is called ASCII. All that ASCII says is that the numbers form 0 to 255 can also represent small and capital letters, punctuation etc. Whenever you write A, rest assured somewhere in memory, a 65 was stored. A file on disk can also contain numbers form 0 to 255 only and the same rule as spelt above apply.
a.cs class zzz { public static void Main() { char i = 'a'; System.Console.WriteLine((char)i); } } Output a

C# offers us the data type char to represent ASCII values naturally.


a.cs class zzz { public static void Main() { int i; for ( i=0; i<=255; i++) System.Console.Write(i + " " + (char)i + " "); } }

The above program displays the entire Ascii table. The problem with Ascii is that it is sufficient for a language like English, which does not have to many symbols to represent. However, when it comes to visual languages like Japanese, they have more symbols to represent than English. Ascii can represent a max of 256 unique symbols. The industry thus invented Unicode which uses 2 bytes for every character unlike Ascii's one. All the languages of the world can be represented by Unicode. C# understands Unicode and thus the char data type store characters internally as Unicode and not Ascii. The present Unicode standard is 3.0.
a.cs class zzz { public static void Main() { int int; } } Compiler Error a.cs(5,5): error CS1041: Identifier expected, 'int' is a keyword a.cs(5,8): error CS1001: Identifier expected

Words like int, char, if etc are reserved by C# and we are not allowed to use them as function names, class names, variable names etc. However, if you insist on doing so, then you have to preface the name with a @ sign like below.
a.cs class zzz { public static void Main() { int @int; } } Compiler Warning a.cs(5,5): warning CS0168: The variable 'int' is declared but never used

The warning does not name the variable @int but int.
a.cs class zzz { public static void Main() { int @int; @int = 10; System.Console.WriteLine(@int); } } Output 10

We have millions of names to choose for a variable, then why insist on an int. There will be times when another language declares a name as a reserved name and in those cases we would use the @ sign. It is advisable not to use the @ sign very often. When we run the C# compiler on our program, it does 2 things. One, it reads our code and converts it into things/tokens it understands. This is called a Lexical analysis. Then it does a Syntactic analysis which gives us an executable output.

Comments
Comments are a form of documentation. They are lines of code written for our benefit (the community of programmers) and not for C#'s. In spite of this, programmers in general are lazy in writing comments. Comments are ignored by the compiler.
a.cs // hi this is comment class zzz { public static void Main() // allowed here { /* A comment over two lines */ } }

A regular comment starts with a /* and ends with a */. They can be spread over multiple lines and can be placed anywhere in your code. Any line beginning with a // is a one line comment and as the name suggests, cannot span multiple lines. A single line comment does not have to be at the beginning of a line.

Escape Sequences and Strings


a.cs class zzz { public static void Main() { System.Console.WriteLine("hi \nBye\tNo"); System.Console.WriteLine("\\"); } } Output hi Bye No \

An escape sequence is anything that starts with a \. A \n means start printing from a new line and a \t means a tab. Two backslashes convert into a single backslash.
a.cs class zzz { public static void Main() { System.Console.WriteLine(@"hi \nBye\tNo"); } } Output hi \nBye\tNo

A string is anything in double quotes. A verbatim string starts with a @ sign and all the escape sequences are ignored by the C# compiler and displayed verbatim.
a.cs class zzz { public static void Main() { System.Console.WriteLine("hi bye"); } } Compiler Error a.cs(5,26): error CS1010: Newline in constant a.cs(6,6): error CS1010: Newline in constant

A string cannot spawn multiple lines.


a.cs class zzz { public static void Main()

{ System.Console.WriteLine(@"hi bye"); } } Output hi bye

Placing an @ in front of the string lets it spawn multiple lines and the spaces shown in the output. If you want the \ to lose its special meaning in a string, preface that string with a @ sign.
a.cs class zzz { public static void Main() { string a = "bye"; string b = "bye"; System.Console.WriteLine(a == b); } } Output True

The above example displays true, even though the two strings may be stored in different areas of memory. The two strings contain the same characters and hence are similar.

The Preprocessor
Before the C# compiler can start, a small part of it called the pre-processor first activates itself. It is called the preprocessor as the same concept existed in the programming language 'C'. All that the preprocessor does is that it looks at those lines beginning with a # symbol.
a.cs #define vijay class zzz { public static void Main() { } }

The first preprocessor directive we are learning is called define. This lets us create a word/variable or even better, an identifier called vijay. The identifier vijay has no value other than true.
a.cs class zzz { public static void Main() { #define vijay } } Compiler Error a.cs(5,2): error CS1032: Cannot define/undefine preprocessor symbols after first token in file

We cannot use the #define, after valid C# code has been written. They have to come at the beginning of the file.
a.cs #define vijay class zzz { public static void Main() { #if vijay System.Console.WriteLine("1"); #endif } } Output 1

As a #define creates a variable, its value can be checked by the if or more precisely the #if which works in the same way as the if of C# does. Thus the #if is true and all code up to the #endif gets added to the code.
a.cs class zzz { public static void Main() { #if vijay System.Console.WriteLine("1"); #else System.Console.WriteLine("2"); #endif } } Output 2

The same rules as before for an else. Here as we have not created an identifier called vijay, it gets a value of false and therefore the #if is false. Imagine a preprocessor identifier as a boolean variable. Why use a preprocessor variable instead of a normal one? Run the C# compiler as follows on the above program and observe the change in output.
csc /D:vijay a.cs Output 1

The output displays 1 as the /D compiler option lets you create identifiers at the time of compiling the program. This cannot be done with a normal variable. We can add/subtract lots of code form our program, at the time of compilation.
a.cs #undef vijay class zzz

{ public static void Main() { #if vijay System.Console.WriteLine("1"); #else System.Console.WriteLine("2"); #endif } } Output 2

As we are allowed to create an identifier vijay by the define, the undef does the reverse. It sets it to false which is the default in any case. As the value of vijay is false, the else gets activated. However we run the above as csc /D:vijay a.cs, we are first creating an identifier vijay at the command line prompt, then undefining it at the first line in the program and the output will show 2 as before. You cannot use the define or undefine after real code.
a.cs #define vijay #undef vijay #undef vijay class zzz { public static void Main() { #if vijay System.Console.WriteLine("1"); #endif } }

People are allowed to nag you as many times as they like. Repetition has been part of human history since ancient times. You are allowed to undef as many times as you like even though it makes no logical sense.
a.cs #define vijay #define mukhi class zzz { public static void Main() { #if vijay #if mukhi System.Console.WriteLine("1"); #endif #endif } } Output 1

You can have as many #if's within #if's. We call them nested if's. If the #if is true, then the text up to the #endif is included.

a.cs #define vijay class zzz { public static void Main() { #if vijay System.Console.WriteLine("1"); #else int int; #endif } }

We get no error at all in spite of the fact that we are not allowed to create a variable called int. Is C# sleeping at the wheel? It is not as the preprocessor realized that the identifier vijay is true, it removed all the code from the #else to the #endif. C# did not flag an error at all, as it was not allowed to see the offending code by the preprocessor.
a.cs class zzz { public static void Main() { #if vijay System.Console.WriteLine("1"); #else int int; #endif } } Compiler Error a.cs(8,5): error CS1041: Identifier expected, 'int' is a keyword a.cs(8,8): error CS1001: Identifier expected

Now we see the error as the identifier vijay is false. Remember what the C# compiler sees is what the preprocessor allows it to. You write code and what the compiler sees may be very very different.
a.cs #warning We have a code red class zzz { public static void Main() { } } Compiler Warning a.cs(1,10): warning CS1030: #warning: 'We have a code red'

Whenever we want a warning message to be displayed at the time of compiling our code we use #warning.
a.cs class zzz { #warning We have a code red public static void Main()

{ } } Compiler Warning a.cs(3,10): warning CS1030: #warning: 'We have a code red'

Unlike the #define, the #warning can be used anywhere in our program. It enables us to add to the messages of the compiler. Also the line number changes from 1 to 3 telling us where the warning occurred.

a.cs class zzz { #error We have a code red public static void Main() { } } Compiler Error a.cs(3,8): error CS1029: #error: 'We have a code red'

Wherever we have warnings, errors cannot be far behind. The difference is that an error unlike a warning, stops everything in its tracks and does not let the compiler proceed ahead. No exe file is created. Normally an error or warning would be placed in an if statement as follows.
a.cs #define vijay #define mukhi class zzz { #if vijay && mukhi #error We have a code red #endif public static void Main() { } } Compiler Error a.cs(6,8): error CS1029: #error: 'We have a code red'

The && means and. The if is true if both sides of the && is true. They are in this case. Remove one of the above #defines and the if will be false.
a.cs #line 100 "vijay" class zzz { #warning We have a code red public static void Main() { } }

Compiler Warning vijay(102,10): warning CS1030: #warning: 'We have a code red'

The line directive does two things. One it changes the line number from 1 which is what is should be at the beginning to 100. Thus the warning appears on line 102 now and not 2. Also the file name changes from a.cs to vijay. You have total control over the line number and file name displayed.
a.cs #line 100 "vijay" class zzz { public static void Main() { int int; #line 200 "mukhi" char char; } } Compiler Error vijay(104,5): error CS1041: Identifier expected, 'int' is a keyword vijay(104,8): error CS1001: Identifier expected mukhi(200,6): error CS1041: Identifier expected, 'char' is a keyword mukhi(200,10): error CS1001: Identifier expected Line does not only work with the #error or #warning. It affects also the compiler's error line number and file name. You are allowed to have as many #lines as you prefer.

--------------------------------------------------------------------------------------------------------------------

7
Function Overloading and Inheritance
Its not what you get but what you give that makes you a richer person. Unfortunately, this little gem is understood only be a few and giving remains largely a one way street. This chapter explains function overloading, the params parameter and inheritance. We start with function overloading.

Function Overloading
a.cs class zzz { public static void Main() { yyy a = new yyy(); a.abc(10); a.abc("bye"); a.abc("no",100); } } class yyy

{ public void abc(int i) { System.Console.WriteLine("abc" + i); } public void abc(string i) { System.Console.WriteLine("abc" + i); } public void abc(string i,int j) { System.Console.WriteLine("abc" + i + j); } } Output abc10 abcbye abcno100

The class yyy has three functions, all of them having the same name abc. The distinction between them is in the data types of the parameters. They are all different. In C# we are allowed to have functions with the same name, but having different data types parameters. The advantage is that we call the function by the same name as by passing different parameters, a different function gets called. This feature is called function overloading. All is fine only if the parameter types to the function are different. We do not have to remember a large number of functions by name. The only reason why function overloading works is that C# does not know a function by name, but by its signature. A signature denotes the full name of the function. Thus the name of a function or its signature is the original function name plus the number and data types of its individual parameters.

a.cs class zzz { public void abc() { } public int abc() { } public static void Main() { } } Compiler Error a.cs(6,12): error CS0111: Class 'zzz' already defines a member called 'abc' with the same parameter types

Here we have two functions abc which differ only in the values they return. As return values do not count in the function signature and the function names are similar, hence the error.
a.cs class zzz {

static void abc(int i) { } public void abc(int i) { } public void abc(string p) { } public static void Main() { } } Compiler error a.cs(6,14): error CS0111: Class 'zzz' already defines a member called 'abc' with the same parameter types

We have 2 abc's, that accept an int and differ only in the addition of a modifier static. They have the same signature as modifiers like static are not considered as part of the function signature. Also, in the next program, we have two abc's with different access modifiers which differ in the parameters, hence signature/name changes causing an error.
a.cs class zzz { void abc(int i) { } void abc( out int i) { i = 10; } void abc( ref int i) { } public static void Main() { } } Compiler Error Microsoft (R) Visual C# Compiler Version 7.00.9254 [CLR version v1.0.2914] Copyright (C) Microsoft Corp 2000-2001. All rights reserved. a.cs(10,6): error CS0663: 'abc' cannot define overloaded methods which differ only on ref and out a.cs(6,6): (Location of symbol related to previous error)

The signature consists of not only the parameter data types, but also the kind of parameters i.e. out ref etc. As function abc takes an int with different modifiers i.e. out etc, the signature on each is different. The signature of a method consists of its name and number and types of its formal parameters. The return type of a function is not part of the signature. No two functions can have the same signature and also non-members cannot have the same name as members. A function/method can be called by four different types of parameters. These are pass by value, reference, output and finally parameter arrays. The parameter modifier is not part of the function signature. Lets now understand what parameter arrays are all about.

Params Parameter

A method declaration creates a separate declaration space. This means that anything created in a method is lost at the end of the method.
a.cs public class zzz { public void abc(int i,string i) {} public void pqr(int i) { string i; } public static void Main() { } } Compiler Error a.cs(3,23): error CS0100: The parameter name 'i' is a duplicate a.cs(6,8): error CS0136: A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'parent or current' scope to denote something else

Parameter names have to be unique. Also, we cannot have a parameter and a variable created in a function block with the same name. In pass by value, the value of the variable is passed. In the case of ref and out, the address of the reference is passed.
a.cs public class zzz { string s = "hi"; public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { abc(ref s,ref s); System.Console.WriteLine(s); } void abc(ref string a, ref string b) { System.Console.WriteLine(s); a="no"; System.Console.WriteLine(s); b = "yes"; System.Console.WriteLine(s); s = "maybe"; } } Output hi no yes maybe

You are allowed to pass the same ref parameter as many times as you desire. In the function abc the string s has a value of hi. Then by changing the string b to no, we are actually changing the string s to no as s is passed by reference. Variables a and s refer to the same string in memory. Changing one changes the other. Again changing b also changes s as they refer to the same string. Thus variables a, b and s refer to the same string in memory.
a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { abc(2,"hi","bye","no"); abc(20,"hi"); abc(2); } void abc(int i , params string [] b) { foreach ( string s in b) System.Console.WriteLine(s + " " + i); } } Output hi 2 bye 2 no 2 hi 20

We will encounter a situation where we would like to pass a variable number of arguments to a function. This is not possible as of now as C# is extremely finicky about the number and type of data we pass to a function. If we pass a string where an int is expected, C# starts screaming like a baby. If we want to pass a variable number of arguments to a function, we have to use a keyword params. This keyword can only be applied to the last parameter. Therefore the variable number of arguments can only come at the end. In the case of function abc, the first parameter has to be an int, the rest of them can be from zero to an infinite number of strings.
a.cs public class zzz { public static void Main() { } void abc(int i , params string [] b , int j) { } } Compiler Error a.cs(6,18): error CS0231: A params or __arglist parameter must be the last parameter in a formal parameter list

The params keyword in this version has to be at the end only as stated above.

a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { abc(2,3,4); abc(20,1); abc(2); } void abc(int i , params int [] b) { foreach ( int s in b) System.Console.WriteLine(s + " " + i); } } Output 32 42 1 20

C# is smart enough if the penultimate parameter and the params have the same data type. The first int is stored in the variable i, the rest are made part of the array b.
a.cs public class zzz { void abc(int i , params string [][] b) { } void abc(int i , params string [,] b) { } } Compiler Error a.cs(6,6): error CS0225: The params parameter must be a single dimensional array

The data type of the params parameter must be, as the error message states, a single dimensional array. Thus [][] is allowed but not [,]. You are also not allowed to combine the params keyword with ref or out.
a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { string [] s = {"hi","bye","no"}; abc(2,s); } void abc(int i , params string [] b) { foreach ( string s in b) System.Console.WriteLine(s + " " + i);

} } Output hi 2 bye 2 no 2

You are allowed to pass an array of strings instead of individual strings as parameters. Here s is an array of strings which has been initialized using the short form. Internally when we call the function abc, C# converts the array of strings into individual strings.
a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { string [] s1 = {"hi","bye"}; abc(2,s1,"hell"); } void abc(int i , params string [] b) { } } Compiler Error a.cs(11,1): error CS1502: The best overloaded method match for 'zzz.abc(int, params string[])' has some invalid arguments a.cs(11,7): error CS1503: Argument '2': cannot convert from 'string[]' to 'string'

Mixing and matching is not allowed in C#. What we assumed C# would do is to add the last string hell to the array of strings s1 or convert s1 to individual strings and then add the string hell to it. Perfectly logical we thought. Only if wishes were horses Internally before calling the function abc, it collects all the individual parameters and converts it into one big array for the params statement.
a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { int [] a = {1,2,3}; abc(2,a); System.Console.WriteLine(a[1]); } void abc(int i , params int [] b) { b[1] = 100;

} } Output 100

The output produced is proof of concept. The array member a[1] has an initial value of 2 and in the function abc we change it to 100. The original changes, this means that the array is given to the function abc.
a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { int a = 10; abc(2,100,a,20); System.Console.WriteLine(a); } void abc(int i , params int [] b) { b[1] = 100; } } Output 10

In this case C# creates an array containing 100 10 and 20. We are changing the second member to 100 which has nothing to do with the variable a. As abc has no knowledge of a, how on earth can abc change the value of the int a? Thus it stays the same.
a.cs public class zzz { public static void Main() { zzz z = new zzz(); z.pqr(); } void pqr() { abc(2); abc(2,3); abc(2,3,5,6); } void abc(int i, int j) { System.Console.WriteLine("two ints "+ i + " " + j); } void abc(params int [] a) { System.Console.WriteLine("params a"); } }

Output params a two ints 2 3 params a

Here we are discussing function overloading. C# is extremely bright though partial. It does not like the params statement and treats it like a stepchild. When we call abc with one int, C# can only call the abc that takes a params as a parameter as it matches one int. An array can contain one member. The fun starts with the abc that is being called with two ints. Here we have a dilemma. C# can call the params abc or the abc with two ints. As mentioned earlier, C# treats the params as a second class citizen and therefore chooses the abc with two ints. When there are more than two ints like in the third invocation, C# has no choice but to grudgingly choose the abc with the params. C# chooses the params as a last resort before flagging an error.
a.cs using System; class zzz { static void ff(params object[] b) { foreach (object o in b) { Console.Write(o.GetType().FullName + " "); } Console.WriteLine(); } static void Main() { object[] a = {1, "Hello", 123.456}; object o = a; ff(a); ff((object)a); ff(o); ff((object[])o); } } Output System.Int32 System.String System.Double System.Object[] System.Object[] System.Int32 System.String System.Double

In the first case we are passing the function ff an array of object that looks like object. We will tell you a little later that all classes are derived from object. The function ff receives an array of objects b. In the foreach we know that the object class has a function GetType that returns an object that looks like Type, which in turn has a function called FullName which returns the name of the type. We see three different types displayed. In the second invocation of ff we are casting a to an object. There is no conversion available from converting an object to an object array i.e. object []. Therefore a one element object [] is created. It's the same case in the third invocation and the last explicitly casts to an object array.
a.cs using System; class zzz { static void ff(params object[] b) { Console.WriteLine(b.GetType().FullName); Console.WriteLine(b.Length); Console.WriteLine(b[0]); } static void Main() { object[] a = {1, "Hello", 123.456};

ff((object)a); } } Output System.Object[] 1 System.Object[]

Inheritance
a.cs class zzz { public static void Main() { xxx a = new xxx(); a.abc(); } } class yyy { public int i = 10; public void abc() { System.Console.WriteLine("yyy abc"); } public void pqr() { System.Console.WriteLine("yyy pqr"); } } class xxx { } Compiler Error a.cs(6,1): error CS0117: 'xxx' does not contain a definition for 'abc'

The class yyy contains 2 functions and one instance variable. The class xxx contains no code and no variables at all. An empty class does not denote any error as we are able to instantiate an object that looks like xxx. The error comes about because the class xxx has no function called abc. However the class yyy has a function abc. Would it not be great if we were allowed to use all the code in the class yyy from xxx. Easier said than done, we guess!
a.cs class zzz { public static void Main() { xxx a = new xxx(); a.abc(); } } class yyy { public int i = 10; public void abc() { System.Console.WriteLine("yyy abc");

} public void pqr() { System.Console.WriteLine("yyy pqr"); } } class xxx : yyy { } Output yyy abc

The error disappears and the abc in yyy gets executed. If after the name of the class you write : yyy i.e. the name of another class, a lot happens at once. xxx is now said to have been derived from yyy. What that means is all the code we wrote in yyy can now be used in xxx. It is if we actually wrote all the code that is contained in yyy in xxx. If we had created an object that looks like yyy, everything that the object could do, now an object that looks like xxx can also do. But we have not written a line of code in xxx. We are made to believe that xxx has one variable i and two functions abc and pqr as yyy contains these two functions. Here we are teaching you the concepts of inheritance where yyy will now be called the base class, xxx the derived class.
a.cs class zzz { public static void Main() { xxx a = new xxx(); a.abc(); } } class yyy { public int i = 10; public void abc() { System.Console.WriteLine("yyy abc"); } public void pqr() { System.Console.WriteLine("yyy pqr"); } } class xxx : yyy { public void abc() { System.Console.WriteLine("xxx abc"); } } Compiler Warning a.cs(23,13): warning CS0108: The keyword new is required on 'xxx.abc()' because it hides inherited member 'yyy.abc()' Output xxx abc

Nothing in the world stops class xxx from creating a function abc i.e. one with the same name as in the base class . C# simply gives us a warning. When we run a.abc(), C# first checks whether the class xxx (as a looks like xxx) has a function called abc. If it does not, then it will check in the base class. Earlier abc was only available in the base class and hence got executed. Here as it is already there in xxx, it gets called from xxx and not yyy. Remember the derived classes get a first shot at execution, then the base class. The reason being, the base class may have a number of functions and for various reasons you may not be satisfied with what they do. You should have the right to have your copy of the function to be called. In other words the derived classes functions override the ones in the base class.
a.cs class zzz { public static void Main() { xxx a = new xxx(); a.abc(); } } class yyy { public int i = 10; public void abc() { System.Console.WriteLine("yyy abc"); } public void pqr() { System.Console.WriteLine("yyy pqr"); } } class xxx : yyy { public void abc() { System.Console.WriteLine("xxx abc"); base.abc(); } } Output xxx abc yyy abc

What if you want the best of both worlds? You may want to call the base classes abc first and then yours or vice versa. To accomplish this, C# gives you a reserved word, something free called base. The word base can be used in any derived class. It means call the function off the base class. Simple. Thus base.abc will call the function abc from yyy the base class of xxx.
a.cs class zzz { public static void Main() { xxx a = new xxx(); a.abc(); } } class yyy {

public int i = 10; public void abc() { System.Console.WriteLine("yyy abc"); } public void pqr() { System.Console.WriteLine("yyy pqr"); } } class xxx : yyy { public void abc() { System.Console.WriteLine("xxx abc"); base.pqr(); } } Output xxx abc yyy pqr

There is only one small change made to the program and that is base.abc is replaced by base.pqr. In this case the function pqr from the class yyy gets called. Base is very general purpose. It lets you access members of the base class from the derived class. You cannot use base in yyy as yyy is not derived from any class. Thus base can only be used in derived classes.
a.cs class zzz { public static void Main() { yyy a = new yyy(); a.xyz(); } } class yyy { public void abc() { System.Console.WriteLine("yyy abc"); } } class xxx : yyy { public void xyz() { } } Compiler Error a.cs(6,1): error CS0117: 'yyy' does not contain a definition for 'xyz'

In this case, xxx is derived from yyy and not vice versa. Thus xxx can use all the members of yyy. Inheritance does not work backwards. Whatever members xxx comprises do not permeate upwards to yyy. Class xxx may now have a function xyz but it cannot give it to class yyy and thus an error occurs.

A class inherits everything from its base class except the constructors and destructors. If a class c is derived from class b, which in turn has been derived from class a, class c inherits all the members declared in class b and also class a. This concept is called transitive. A derived class can inherit all the members of the base class but cannot subtract or remove members off that base class. A derived class can hide members of the base class by creating functions by the same name. The original member in the base class remains unchanged and unaffected by whatever is happening in the derived class. It remains unchanged in the base class, it is simply not visible in the derived class. A class member can either be a static member belonging to the class or an instance member belonging to the instance i.e. accessible through the object and not the class. The default is non-static. A class is also called a data structure. It consists of data members like constants, fields and events and function members like methods, properties, indexers, operators, constructors, static constructors and destructors. A class within a class is called a nested class. Thus we can place 11 different types of entities in a class. Function members are the only members of a class that contain executable code. A class creation creates a new declaration space. All classes derive from object . Object is the mother of all classes.
a.cs public class zzz : object { public static void Main() { } }

If you do not derive from any class, then the C# compiler automatically adds :object to your class definition. Object, the only class to have this feature is not derived from any class. It is the ultimate base class of all classes in the C# hierarchy.
class aa { } class bb : aa { }

Class aa is the base class of bb . The documentation however calls aa the direct base class of bb. Thus the base classes of bb are aa and object.
a.cs public class zzz { public static void Main() { } } class aa : System.Delegate { } class bb : System.Enum { } class cc : System.Array { } class dd : System.ValueType

{ } Compiler Error a.cs(7,7): error CS0644: 'aa' cannot inherit from special class 'System.Delegate' a.cs(10,7): error CS0644: 'bb' cannot inherit from special class 'System.Enum' a.cs(13,7): error CS0644: 'cc' cannot inherit from special class 'System.Array' a.cs(16,7): error CS0644: 'dd' cannot inherit from special class 'System.ValueType'

You cannot derive a class from the above 4 classes as they are special.
a.cs public class zzz { public static void Main() { } } class aa { } class bb { } class cc : aa, bb { } Compiler Error a.cs(9,16): error CS0527: 'bb' : type in interface list is not an interface

A class can only be derived from one more class . You are not permitted to derive from two or more classes i.e. multiple inheritance is not supported. Thus every class has one and only one base class.
a.cs public class zzz { public static void Main() { } } class aa : bb { } class bb : cc { } class cc : aa { } Compiler Error a.cs(13,7): error CS0146: Circular base class definition between 'cc' and 'aa'

class aa is derived from bb. Class bb in turn is derived from cc and cc is derived from aa. This results in a circular definition. class aa is derived from bb and cc, as bb is derived from cc. As cc is also derived from aa class, bb also derives from this class which is aa. Thus aa is derived from aa which is a logical impossibility.

Equating Objects
a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); a = b; b = a; } } class yyy { public int i=10; } class xxx { public int j=10; } Compiler Error a.cs(7,5): error CS0029: Cannot implicitly convert type 'xxx' to 'yyy' a.cs(8,5): error CS0029: Cannot implicitly convert type 'yyy' to 'xxx'

C# has a very simple rule. It does not like you to equate different objects to each other. Thus an object that looks like yyy cannot be equated to one that looks like xxx and vice versa. Thus the error. Another example - you cannot take an int and equate it to a string . C# is extremely strict when it comes to dealing with different data types.
a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); a = b; b = a; } } class yyy { public int i=10; } class xxx : yyy { public int j=10; } Compiler Error a.cs(8,5): error CS0029: Cannot implicitly convert type 'yyy' to 'xxx'

There is however one way out. On account of this way, one of the errors disappeared. The only time we are allowed to equate dissimilar data types is when we derive from them. Lets explain this in detail.

When we create an instance of yyy by saying new, we are creating two objects at one go, one that looks like yyy and the other that looks like object. All classes in C# are finally derived from object. As xxx is derived from yyy, when we say new xxx, we are creating 3 objects, one that looks like yyy, one that looks like xxx and finally object. Thus when we write a = b, b looks like xxx, yyy and object and as a looks like yyy, there is a match at yyy. Consequence? No error. Even though a and b have the same values, using a we can only access the members of yyy, even though had we used b we could access xxx also. We have devalued the potency of a . The error arises at b = a, because the class yyy is less/smaller than the class xxx . The class xxx has yyy and more. We cannot have a larger class on the right and a smaller class on the left. a only represents a yyy whereas b expects a xxx which is a xxx and yyy. The basic rule is that we can only equate dissimilar objects if they are derived from each other. You can equate an object of a base class to a derived class but not vice versa.
a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); a = b; b = (xxx) a; } } class yyy { public int i=10; } class xxx : yyy { public int j=10; }

Though we broke a C# rule on equating objects, we did not get an error because of the cast . A () is called a cast. Within the brackets we put the name of a class. A cast is the great leveler. When we write b = a, C# expects the right hand side of the equal to to be a b i.e. a xxx . Instead it finds a i.e. a yyy . So by applying a cast, we are for the moment converting the yyy object into an xxx. This strategy satisfies the rules of C# on only equating similar objects. Remember it is only for the duration of the line that a becomes a xxx and not a yyy.
a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); a = (yyy) b; b = (xxx) a; } } class yyy { public int i=10; } class xxx { public int j=10;

} Compiler Error a.cs(7,6): error CS0030: Cannot convert type 'xxx' to 'yyy' a.cs(8,6): error CS0030: Cannot convert type 'yyy' to 'xxx'

Unfortunately casting works only if one of the two classes is derived from the other. You cannot cast any two objects to each other.
a.cs class zzz { public static void Main() { int i = 10; char j = 'A'; i = j; j = i; } } Compiler Error a.cs(8,5): error CS0029: Cannot implicitly convert type 'int' to 'char' We are allowed to convert a char into a int as i = j but not the other way round as j = i.

8
Modifiers Access Modifiers
Public, Private, Protected and Internal

Whenever a class is created by us we want to have the ability to decide who can access certain members of the class. In other words, we would like to restrict access to the members of the class. The basic rule is that members of a class can freely access each other. There is no way one can prevent a function of a particular class from executing another function in the same class. By default though, the same class is allowed complete access but no one else is granted access to the members of the class. The default access modifier is private.
a.cs class zzz { public static void Main() { yyy.pqr(); } } class yyy

{ static void abc() { System.Console.WriteLine(yyy abc); } public static void pqr() { System.Console.WriteLine(yyy pqr); abc(); } } Output yyy pqr yyy abc

Pqr is public and hence anyone is allowed to execute it. abc has no access modifier which makes it private, which is anyway the default. The private modifier has no effect on members of the same class and hence pqr is allowed to call abc. This concept is called member access.
a.cs class zzz { public static void Main() { yyy.abc(); } } class yyy { static void abc() { System.Console.WriteLine(yyy abc); } public static void pqr() { System.Console.WriteLine(yyy pqr); abc(); } } Compiler Error a.cs(5,1): error CS0122: yyy.abc() is inaccessible due to its protection level

abc is private an no one but members of yyy can access it.


a.cs class zzz { public static void Main() { yyy.abc(); } } class yyy { protected static void abc() { System.Console.WriteLine(yyy abc); } public static void pqr() { System.Console.WriteLine(yyy pqr);

abc(); }} Compiler Error a.cs(5,1): error CS0122: yyy.abc() is inaccessible due to its protection level

We have now introduced one more access modifier, protected, which also does not let you access a class from outside. However pqr is allowed to access abc as access modifiers do not effect the same class as mentioned earlier.
a.cs class zzz { public static void Main() { xxx.aaa(); } } class yyy { static void abc() { System.Console.WriteLine(yyy abc); } public static void pqr() { System.Console.WriteLine(yyy pqr); } protected static void xyz() { System.Console.WriteLine(yyy xyz); } } class xxx : yyy { public static void aaa() { abc(); pqr(); xyz(); } } Compiler Error a.cs(27,1): error CS0122: yyy.abc() is inaccessible due to its protection level

We are now dealing with derived classes. When we flag a function with the modifier, protected, we are informing C# that only derived classes can access the function. Nobody else can. Thus in function aaa we can call xyz as it is flagged protected, but it cannot be called from anywhere else including Main. The function abc is private and can be called only from the class yyy. Comment out abc(); in aaa and csc will show you no errors. To sum up, we have learnt three concepts. Private means only the same class has access, public means everyone has access and protected lies in between where only derived classes have access. All functions for example reside in a class. The accessibility of that function is decided by the class in which it resides as well as the modifiers on the function. If we are allowed access to a member, we say that the member is accessible, else inaccessible.
b.cs

internal class yyy { } csc /t:library b.cs

This command will produce a library b.dll with one class yyy.
a.cs class zzz { public static void Main() { yyy a; } } >csc a.cs /r:b.dll Compiler Error a.cs(5,1): error CS0122: yyy is inaccessible due to its protection level

We get the above error as the modifier internal means that we can only access yyy from b.dll and not from any other file or program. Never create a component and flag the class internal as no one would be able to use it. Internal means access limited to this program only. Also writing csc a.cs b.cs would not give us any error.
a.cs public namespace vijay { class zzz { public static void Main() { } } } Compiler Error a.cs(1,8): error CS1518: Expected class, delegate, enum, interface, or struct

Namespaces by default can have no accessibility modifiers at all. They are public by default and we cannot add any other access modifier including public again.
a.cs private class zzz { } Compiler Error a.cs(1,1): error CS1527: Namespace elements cannot be explicitly declared as private or protected

A class can only be public or internal. It cannot be marked as protected or private. The default is internal.
b.cs class yyy {

} csc b.cs /t:library Compiler Error fatal error CS2022: Options /out and /target must appear before source file names

Mistake, done on purpose. At times we will forget to tell you that some compiler options like /t and /out must appear before the names of the source files.
>csc /t:library b.cs a.cs class zzz { public static void Main() { yyy a; } } >csc a.cs /r:b.dll Compiler Error a.cs(5,1): error CS0122: yyy is inaccessible due to its protection level

Thus if we want other programs/files to access classes created by us, we must not forget that by default they are marked as internal as explained earlier. Members of a class can have all the modifiers described above and default to private.
a.cs class zzz { public static void Main() { } public private void abc() { } } Compiler Error a.cs(6,8): error CS0107: More than one protection modifier

You are not allowed more than one access modifier most of the time. The exceptions, we will soon take care off. Predefined types like int, object have no accessibility restrictions. They can be used anywhere and everywhere.
b.cs class yyy { public void abc() { } } csc /t:library b.cs

a.cs class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } Compiler Error a.cs(5,1): error CS0122: 'yyy' is inaccessible due to its protection level a.cs(6,1): error CS0246: The type or namespace name 'a' could not be found (are you missing a using directive or an assembly reference?)

As the class yyy has not been specified by an access modifier, it is by default internal. Even though abc is public, the type enclosing it i.e. yyy is internal and hence no member of yyy can be accessed from outside b.cs. Thus the access modifiers of the class and the members is important.
b.cs public class yyy { void abc() { } } >csc /t:library b.cs a.cs class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } Compiler Error a.cs(6,1): error CS0122: yyy.abc() is inaccessible due to its protection level

Here yyy is accessible as the modifier is public but the function abc is private and hence cannot be accessed by anyone but the class. From now on we will only display a.cs and b.cs as the command line executions of the compiler will remain the same. a.cs remains the same for this program.
b.cs public class yyy { internal void abc() { } } Compiler Error a.cs(6,1): error CS0122: yyy.abc() is inaccessible due to its protection level

Internal means no one from outside the dll can access the function.

a.cs class zzz { public static void Main() { ppp a = new ppp(); a.aaa(); } } b.cs public class yyy { protected internal void abc() { } } public class xxx : yyy { void pqr() { abc(); } } public class ppp { public void aaa() { yyy a = new yyy(); a.abc(); } }

No error occurs as protected internal means two things. It is either derived classes or classes in the same file that can access abc. Therefore derived class xxx can use it as well as class ppp. What we are trying to get at here is that the containing type decides first the accessibility and then the member modifiers also comes in. Making the class internal and then the members public will in no way allow classes in others files access it.
a.cs class zzz { public static void Main() { } } class yyy { protected int x; void abc( yyy a , xxx b) { a.x = 1; b.x = 2; } } class xxx : yyy { void pqr( yyy a , xxx b)

{ a.x = 1; b.x = 2; }} Compiler Error a.cs(20,1): error CS1540: Cannot access protected member yyy.x via a qualifier of type yyy; the qualifier must be of type xxx (or derived from it)

Class yyy contains a protected member x. To the same class no modifiers make sense. However as x is protected, in the derived class function pqr, we cannot access it through yyy as a.x gives us an error. However b which looks like xxx does not give an error. To check this out, comment out the line a.x=1 in pqr(). This means that we can access the protected members not from an object of the base class, but from the derived class objects only. This is in spite of the fact that x is a member of yyy, the base class. Even so, we still cannot access it. Also we cannot access x from the function Main.
a.cs class zzz { public static void Main() { } } class yyy { } public class xxx : yyy { } Compiler Error a.cs(10,14): error CS0060: Inconsistent accessibility: base class yyy is less accessible than class xxx

Between internal and public, public allows greater access to its members. The class yyy is by default internal and xxx which derives from yyy is explicitly made public. We get an error as the derived class yyy has to have an access modifier which allows greater access than the base class access modifier. Here internal is more restrictive than public.
a.cs class zzz { public static void Main() { } } public class yyy { } class xxx : yyy { }

If we reverse the modifiers, i.e. we make yyy public and xxx the derived class internal we get no error. The base class allows more accessibility than the derived class.
a.cs class zzz { public static void Main()

{ } } class yyy { } public class xxx { public yyy f() { return new yyy(); } } Compiler Error a.cs(12,12): error CS0050: Inconsistent accessibility: return type yyy is less accessible than method xxx.f()

The accessibility of yyy is internal which is more restrictive than public. The accessibility of function f is public which is more than that of the type yyy. The error occurred as return values must have greater accessibility than that of the method, which is not true in this case.
a.cs class zzz { public static void Main() { } } class yyy { } public class xxx { public yyy a; } Compiler Error a.cs(12,12): error CS0052: Inconsistent accessibility: field type yyy is less accessible than field xxx.a

Rules are rules they remain the same everywhere. The class yyy or data type yyy is internal. a, an object/field is public which makes it more accessible than yyy which is internal. Hence the error.
a.cs class zzz { public static void Main() { } } class yyy { } public class xxx { yyy a; }

Now we get no error as a has been made private which gives it a lower accessibility than yyy which is internal. Logic is that whatever you create must be more accessible than what you create from.

Sealed Classes
Sealed is another modifier that applies to classes. aaa is a sealed class. No class can derive from aaa. In another words aaa cannot act as a base class for any class.
a.cs public class zzz { public static void Main() { } } sealed class aaa { } class bbb : aaa { } Compiler Error a.cs(10,7): error CS0509: bbb : cannot inherit from sealed class aaa a.cs public class zzz { public static void Main() { aaa a = new aaa(); System.Console.WriteLine(a.i); a.abc(); } } sealed class aaa { public int i = 9; public void abc() { System.Console.WriteLine(hi); } } Output 9 hi

The only difference between a sealed class and a non-sealed class is that a sealed class cannot be derived from. Otherwise there is no difference at all. It can contain the same variables, functions etc as a normal class does . A sealed class lets us create classes which no one can derive from. Thus the code in such classes cannot be overridden. Also as the compiler knows this, certain run time optimizations can be performed on a sealed class

Constants
a.cs public class zzz { const int i = 10;

public static void Main() { System.Console.WriteLine(i); } } Output 10

A constant or const variable behaves as a variable. We give it an initial value and can use it wherever we can use a variable.
a.cs public class zzz { const int i = 10; public static void Main() { i++; System.Console.WriteLine(i); i = 30; } } Compiler Error a.cs(6,1): error CS0131: The left-hand side of an assignment must be a variable, property or indexer a.cs(8,1): error CS0131: The left-hand side of an assignment must be a variable, property or indexer

Unlike a variable, we are not allowed to change the value of a const. The change is an assignment statement.
a.cs public class zzz { const int i ; public static void Main() { i = 30; System.Console.WriteLine(i); } } Compiler Error a.cs(3,13): error CS0145: A const field requires a value to be provided

We have to initialize the const variable at the time of creation. We are not allowed to initialize it later in our program.
a.cs public class zzz { const int i = j + 4; const int j = k - 1; const int k = 3; public static void Main() { System.Console.WriteLine({0} {1} {2},i,j,k); } }

Output 623

A constant can depend upon another constant. C# is smart enough to realize that to calculate the value of const i, it first needs to know the value of j. js value depends upon another const k, whose value is 3. Thus C# first evaluates k to 3 then j becomes 2 i.e. k -1 and finally i takes on the value of j i.e. 2 + 4 resulting in 6. Like classes consts cannot be circular i.e., they cannot depend upon each other.
a.cs public class zzz { const int i = j + 4; const int j = k - 1; const int k = i; public static void Main() { System.Console.WriteLine({0} {1} {2},i,j,k); } } Compiler Error a.cs(3,11): error CS0110: The evaluation of the constant value for zzz.i involves a circular definition

The value of the const i depends upon j which in turn depends upon k, which is equal to i. This becomes a circular definition. A const is a variable whose value cannot be changed but whose initial value is compile time determined.
a.cs public { public public { } } public { } class zzz const aa a = new aa(); static void Main()

class aa

Compiler Error a.cs(3,17): error CS0133: The expression being assigned to zzz.a must be constant a.cs public { public public { } } public { } class zzz const aa a = null; static void Main()

class aa

The error vanishes as we are now initializing a to an object which has a value that can be determined at compile time. We cannot ever change the value of a, so it will always be null. Normally we do not have consts as a reference type as they have value only at runtime. As mentioned earlier we can only initialize a const to a compile time value i.e. a value available to the compiler while it is executing. new unfortunately gets executed at runtime and therefore has no value at compile time. This gives us an error.
a.cs class zzz { public static void Main() { yyy y = new yyy(); System.Console.WriteLine(y.i); } } class yyy { public const int i = 3; } Compiler Error a.cs(6,26): error CS0176: Static member 'yyy.i' cannot be accessed with an instance reference; qualify it with a type name instead

A constant is static by default and we cannot use the instance reference i.e. a name to reference a const. A const has to be static as no one is allowed to make any changes to a const.
a.cs class zzz { public static void Main() { } } class yyy { public static const int i = 3; } Compiler Error a.cs(9,25): error CS0504: The constant yyy.i cannot be marked static

C# does not want us to repeat the obvious over and over again. Just like humans, programming language too have their own quirks. Some other time, perhaps, C# may permit us to write a static before an entity that is already static by default.
a.cs class zzz { public static void Main() { System.Console.WriteLine(yyy.i + + xxx.i); } } class yyy { public const int i = 3; }

class xxx : yyy { public const int i = 30; } Compiler Warning a.cs(14,18): warning CS0108: The keyword new is required on xxx.i because it hides inherited member yyy.i Output 3 30

We can create a const with the same name as another const in the base class. The const of the class xxx i will hide the const i in class yyy for the class xxx only.

Fields
A field to start with is another word for a variable in a class. There are a large number of generic rules that apply to all members of a class and we will not tire you by repeating them ad nauseam. A variable can never have an uninitialized value in C#.
a.cs public class zzz { static int i; static bool j; public static void Main() { System.Console.WriteLine(zzz.i + + zzz.j ); }} Output 0 False

Static variables are initialized when the class is loaded first. An int is given an initial value of zero and a bool False.
a.cs public class zzz { int i; bool j; public static void Main() { zzz a = new zzz(); System.Console.WriteLine(a.i + + a.j ); }} Output 0 False

An instance variable is initialized at the time of creation. The keyword new will create an instance of the zzz. It will allocate memory for each of the non static variables and then initialize each of them to their default values.
a.cs public class zzz { static int i = j + 10;

static int j = i + 1; public static void Main() { System.Console.WriteLine(zzz.i + + zzz.j ); } } Output 10 11

Outputs make a lot of sense if you understand them in plain simple English. C# always initializes static fields to their initial value after creating them . Variables i and j are thus given a default of zero. Then C# realizes that these variables need to be assigned some values. It does not read all the lines, only one at a time. It will now read the first line and as the variable j has a value of 0, i will get a value of 10. Then at the next line, j is the value of i plus 1. The variable i has a value of 10 and j now becomes 11. As it does not see both lines at the same time, it does not notice the circularity of the above definition. In short, though the above example works, it is frowned upon by the powers to be at C#.
a.cs public class zzz { int i = j + 10; int j = i + 1; public static void Main() { } } Compiler Error a.cs(3,9): error CS0236: A field initializer cannot reference the nonstatic field, method, or property zzz.j a.cs(4,9): error CS0236: A field initializer cannot reference the nonstatic field, method, or property zzz.i

It does not work for instance variables as the rules of an instance variable are different than that of static. The field initializer of an instance variable has to be determined at the time of creation of the object. The variable j does not have a value at this point in time. It cannot refer to variables of the same instance at the time of creation. Thus we can refer to no instance members to initialize an instance member. Textual order means first come first served.

Readonly Fields
Fields can be also tagged with the modifier readonly.
a.cs public class zzz { public static readonly int i = 10; public static void Main() { System.Console.WriteLine(i); } } Output 10

No errors at all. However, remember if we use a non static variable in a static function we will get an error.

a.cs public class zzz { public static readonly int i = 10; public static void Main() { i = 20; System.Console.WriteLine(i); } } Compiler Error a.cs(6,1): error CS0198: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

You cannot change the value of a readonly field after its being given an initial value.
a.cs public class zzz { public static readonly int i ; public static void Main() { } }

Unlike a const, a readonly field does not have to be initialized at the time of creation.
a.cs public class zzz { public static readonly int i ; static zzz() { i = 20; System.Console.WriteLine(In Const); } public static void Main() { System.Console.WriteLine(i); } } Output In Const 20

A static readonly field can be initialized in a static constructor also. This is the major difference between a const and a readonly field.
a.cs public { public public { } } public { } class zzz readonly aa a = new aa(); static void Main()

class aa

The same example which gave an error with const does not give an error with readonly. To sum up a readonly is a more generic const and it makes our programs more readable as we refer to a name and not a number. Is 100 more intuitive or priceofcopper easier to understand? The compiler would for reasons of efficiency convert all consts and readonly variables to the actual values.
a.cs public { public { } } public { public } class zzz static void Main()

class aa int readonly i = 10;

Compiler Error a.cs(9,12): error CS1585: Member modifier readonly must precede the member type and name a.cs(9,23): error CS1519: Invalid token = in class, struct, or interface member declaration

Wherever you can place multiple modifiers, remind yourself that there are rules that decide the order of modifiers, which comes first. Here the readonly modifier precedes the data type int. Once again, no great cosmic law responsible, just a rule that must be remembered.
a.cs public class zzz { public static void Main() { } } public class aa { public readonly int i = 10; void abc(ref int z) { } void pqr() { abc(ref i); } } Compiler Error a.cs(13,9): error CS0192: A readonly field cannot be passed ref or out (except in a constructor) A readonly field cannot be changed by anyone except a constructor. The function abc expects a ref parameter which if you have forgotten allows you to change the value of the original. Thus C# does not permit a readonly as a parameter to a function that accepts a ref or a out parameters.

9
Virtual Functions - new and override
Every breath you take, And every move you make Every bond you break, every step you take Ill be watching you -Every Breath You Take,Sting

New and Override Methods


a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); yyy c = new xxx(); a.abc();a.pqr();a.xyz(); b.abc();b.pqr();b.xyz(); c.abc();c.pqr();c.xyz(); } } class yyy { public void abc() { System.Console.WriteLine(yyy } public void pqr() { System.Console.WriteLine(yyy } public void xyz() { System.Console.WriteLine(yyy } } class xxx : yyy { public void abc() { System.Console.WriteLine(xxx } public void pqr() {

abc);

pqr);

xyz);

abc);

System.Console.WriteLine(xxx pqr); } public void xyz() { System.Console.WriteLine(xxx xyz); } } Compiler Warning a.cs(30,13): warning CS0108: The keyword new is required on 'xxx.abc()' because it hides inherited member 'yyy.abc()' a.cs(34,13): warning CS0108: The keyword new is required on 'xxx.pqr()' because it hides inherited member 'yyy.pqr()' a.cs(38,13): warning CS0108: The keyword new is required on 'xxx.xyz()' because it hides inherited member 'yyy.xyz()' Output yyy abc yyy pqr yyy xyz xxx abc xxx pqr xxx xyz yyy abc yyy pqr yyy xyz

Class xxx derives from class yyy. That makes xxx the derived class and yyy the base class. The class xxx comprises yyy and more. Thus can we not conclude, albeit in broken English that an object that looks like xxx is bigger than one that looks like yyy. In C#, you can equate a smaller object to a bigger object as stated earlier. Lets take the case of object a. It looks like yyy and initialized by creating an object that also looks like yyy. When we call the functions abc and pqr and xyz through the object a obviously it will call them from yyy. Object b looks like xxx, the derived class. It is initialized to an object that looks like xxx. When we call abc, pqr and xyz through b, it calls abc, pqr and xyz from xxx. Object c again looks like yyy but it is now initialized to an object that looks like xxx which does not give an error as explained earlier. However there is no change at all in the output and the behavior is identical to that of object a. Hence initializing it to an object that looks like yyy or xxx does not seem to matter.
a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); yyy c = new xxx(); a.abc();a.pqr();a.xyz(); b.abc();b.pqr();b.xyz(); c.abc();c.pqr();c.xyz(); } } class yyy {

public void abc() { System.Console.WriteLine(yyy } public void pqr() { System.Console.WriteLine(yyy } public void xyz() { System.Console.WriteLine(yyy } } class xxx : yyy { public override void abc() { System.Console.WriteLine(xxx } public new void pqr() { System.Console.WriteLine(xxx } public void xyz() { System.Console.WriteLine(xxx } }

abc);

pqr);

xyz);

abc);

pqr);

xyz);

Compiler Error a.cs(30,22): error CS0506: xxx.abc() : cannot override inherited member yyy.abc() because it is not marked virtual, abstract, or override

We get an error because we have added two new modifiers, new and override to the functions. The error says to add the modifier virtual to the functions in the base class.
a.cs class zzz { public static void Main() { yyy a = new yyy(); xxx b = new xxx(); yyy c = new xxx(); a.abc();a.pqr();a.xyz(); b.abc();b.pqr();b.xyz(); c.abc();c.pqr();c.xyz(); } } class yyy { public virtual void abc() { System.Console.WriteLine(yyy abc); } public virtual void pqr() { System.Console.WriteLine(yyy pqr); } public virtual void xyz()

{ System.Console.WriteLine(yyy } } class xxx : yyy { public override void abc() { System.Console.WriteLine(xxx } public new void pqr() { System.Console.WriteLine(xxx } public void xyz() { System.Console.WriteLine(xxx } } Output yyy abc yyy pqr yyy xyz xxx abc xxx pqr xxx xyz xxx abc yyy pqr yyy xyz

xyz);

abc);

pqr);

xyz);

There is a single subtle change in the workings of the objects c only and not a and b. Adding the virtual modifier has made all the difference. The difference is in the object c. c looks like the base class yyy but is initialized to an object that looks like the derived class xxx. C# remembers this fact. When we execute c.abc(), C# remembers that object c was initialized by a xxx object and hence it first goes to class xxx. Here the function has a modifier override which in English means, forget about the data type of c which is yyy, call abc from xxx as it overrides the abc of the base class. The override modifier is needed as the derived class functions will get first priority and be called. We mean to override the abc of the base class. We are telling C# that this abc is similar to the abc of the base class. New has the exactly the opposite meaning. The function pqr has the new modifier. C.pqr() calls pqr from yyy and not xxx. New means that the function pqr is a new function and it has absolutely nothing to do with the pqr in the base class. It may have the same name pqr as in the base class, but that is only a coincidence. As c looks like yyy, the pqr of yyy gets called even though there is a pqr in xxx. When we do not write any modifier, then it is assumed that we wrote new. Thus every time we write a function, C# assumes it has nothing to do with the base class. These modifiers can only be used if the function in the base class is a virtual function. To us virtual means that the base class is granting us permission to call the function from the derived class and not the base class. We have however one caveat, we have to add the modifier override if our derived class function has to be called.
a.cs class zzz { public static void Main() { yyy a = new xxx(); yyy b = new vvv(); xxx c = new vvv(); a.abc();a.pqr();a.xyz();

b.abc();b.pqr();b.xyz(); c.abc();c.pqr();c.xyz(); } } class yyy { public void abc() { System.Console.WriteLine(yyy } public virtual void pqr() { System.Console.WriteLine(yyy } public virtual void xyz() { System.Console.WriteLine(yyy } } class xxx : yyy { public virtual void abc() { System.Console.WriteLine(xxx } public new void pqr() { System.Console.WriteLine(xxx } public override void xyz() { System.Console.WriteLine(xxx } } class vvv : xxx { public override void abc() { System.Console.WriteLine(vvv } public void xyz() { System.Console.WriteLine(vvv } } Output yyy abc yyy pqr xxx xyz yyy abc yyy pqr xxx xyz vvv abc xxx pqr xxx xyz

abc);

pqr);

xyz);

abc);

pqr);

xyz);

abc);

xyz);

Pretty long example. To reiterate, we are allowed to initialize a base object to a derived object. The other way around will generate an error. This leads to an object of a base class being initialized to an object of

the derived class. The question that now springs to mind is, which function will get called. The one from the base class or the derived class. If the base class object declared the function virtual and the derived class used the modifier override, the derived class function will get called. Otherwise the base class function will get executed. Thus for virtual functions, the data type created is decided at run time. All functions not tagged with virtual are non virtual, and the function to be called is decided at compile time, depending upon the static data type of the object. If the object is initialized to the same data type, none of the above apply. Whenever we have a mismatch, we need rules to resolve the mismatch. Thus we can land up with a situation where an object to a base class can call a function in the derived class. The object a looks like yyy but is initialized to the derived class xxx. a.abc(), first looks into the class yyy. Here it checks whether the function abc is virtual. The answer is an emphatic no and hence everything stops and the function abc gets called from class yyy. a.pqr does the same thing, but the function now is virtual in class yyy. Thus C# looks at the class yyy, the one it was initialized to. Here pqr is flagged with the modifier new. This means that pqr is a new function which has nothing to do with the one in the base class. They only accidentally share the same name. Thus as there is no function called pqr (as it is a new pqr) in the derived class, the one from base class gets called. In the case of a.xyz(), the same steps are followed again, but in the class yyy, we meet the modifier override, which overrides the function in the base class. We are telling C# to call this function in class xxx and not the one in the base class yyy. The object b which also looks like class yyy, is now initialized with an object that looks like vvv and not xxx like before. As abc is non virtual it gets called from yyy. In the case of function pqr, C# now looks into class vvv. Here it sees no function pqr and hence now looks into class xxx. Thus the above rules repeat and it gets called from class yyy. In the case of b.xyz, in class vvv, it is marked new by default and hence this function has nothing to do with the one in class yyy. Hence the one from vvv does not get called but the one from class yyy where it specifies override.
public override void xyz() { System.Console.WriteLine(vvv xyz); }

If we change xyz in class vvv to the above, i.e. we change new to override, the xyz of vvv will get called. The last object c looks like xxx but is now initialized to an object that looks like the derived class vvv. c.abc(), first looks into class xxx where it is marked as virtual. Remember abc is non virtual in class yyy but virtual in xxx. From now on, the function abc is virtual in vvv also but not in class yyy. Virtual is like water, it flows downwards not upwards. As abc is virtual, we now look into class vvv. Here it is marked override and hence abc gets called from class vvv. In the case of pqr, pqr is marked virtual in class yyy and new in xxx, but as there is no function pqr in vvv, none of the modifiers matter at all. Thus it gets called from class xxx. Lastly for function xyz, in class vvv it is marked new. Hence it has no connection with the xyz in class xxx and thus function xyz gets called from xxx and not yyy.
a.cs class zzz { public static void Main() { } } class yyy { public virtual void pqr() {} } class xxx : yyy {

public new void pqr() {} } class vvv : xxx { public override void pqr() { }

Compiler Error a.cs(17,22): error CS0506: vvv.pqr() : cannot override inherited member xxx.pqr() because it is not marked virtual, abstract, or override

We get an error as the function pqr in class xxx is marked new. This means that it hides the pqr of class yyy. Form the viewpoint of class vvv, xxx does not supply a function called pqr. The pqr in class xxx has nothing to do with the pqr in yyy. This means that the function pqr of xxx does not inherit the virtual modifier from the function pqr of class yyy. This is what the compiler is complaining about. As the function pqr in xxx has no virtual modifier, in vvv we cannot use the modifier override. You can, however, use the modifier new and remove the warning.
a.cs class zzz { public static void Main() { yyy a = new vvv(); a.pqr(); xxx b = new vvv(); b.pqr(); } } class yyy { public virtual void pqr() { System.Console.WriteLine(yyy pqr); } } class xxx : yyy { public virtual new void pqr() { System.Console.WriteLine(xxx pqr); } } class vvv : xxx { public override void pqr() { System.Console.WriteLine(vvv pqr); } } Output yyy pqr vvv pqr

and if we remove the override modifier from pqr in vvv we get


public void pqr() {

System.Console.WriteLine(vvv pqr); } Output yyy pqr xxx pqr

Thats the problem with virtual functions. We call them the cause of migraine. The answers are always different from what you expect. Object a looks like a yyy but is initialized to the derived class vvv. As pqr is virtual, C# now looks into class vvv. However before looking into the class, it realizes that in class xxx, pqr is new. This cuts of all connection with the pqr in yyy. Thus the word new is preceded with virtual, otherwise the override modifier would give us an error in class vvv. As pqr in class xxx is new function, having nothing to do with the class yyy, class vvv inherits a new which also has nothing to do with the class yyy. The pqr in class vvv is related to the pqr of class xxx and not of class yyy. Thus the pqr of class yyy gets called. In the second case object b looks like class xxx now but is initialized to an object of class vvv. C# first looks at class xxx. Here pqr is new and virtual, which makes it a unique function pqr. Unfortunately, the pqr in vvv has the override modifier which sees to it that the pqr of vvv hides the pqr of xxx. This calls the pqr of vvv instead. If we remove the override modifier from pqr in class vvv, the default is new, that cuts off the umbilical cord from the pqr of xxx. Thus, as it is, a new function, the pqr of xxx gets called. A virtual function cannot be marked by the modifiers static, abstract or override. A non virtual function is said to be invariant. This means that the same function gets called always, irrespective of whether one exists in the base class or derived class. In a virtual function the run-time type of the instance decides on which function to be called and not the compile-time type as is in the case of non virtual functions. For a virtual function there exists a most derived implementation which gets always gets called.
a.cs class zzz { public static void Main() { yyy a = new vvv(); xxx b = new vvv(); www c = new vvv(); vvv d = new vvv(); a.pqr();b.pqr();c.pqr();d.pqr(); } } class yyy { public virtual void pqr() { System.Console.WriteLine(yyy pqr); } } class xxx : yyy { public override void pqr() { System.Console.WriteLine(xxx pqr); } } class www : xxx { public virtual new void pqr() { System.Console.WriteLine(www pqr);

} } class vvv : www { public override void pqr() { System.Console.WriteLine(vvv pqr); } } Output xxx pqr xxx pqr vvv pqr vvv pqr

One last explanation of virtual with a slightly more complex example involving 4 classes. The first line in Output, xxx pqr, is the result of the statement a.pqr();. We have the function pqr as virtual in class yyy. Hence, when using new, we now proceed to class xxx and not vvv as explained earlier. Here, pqr has an override and C# knows that class www inherits this function pqr. In class www, as it is marked as new, C# will now backtrack and not proceed further to class vvv. Hence the function pqr gets called from class xxx as shown in the output.
public override void pqr() { System.Console.WriteLine(www pqr); }

If we change the function pqr in class www to override, then C# will proceed to class vvv and call the pqr of class vvv as it overrides the pqr of www. Remove the override from pqr in class vvv and the function will get called from class www as the default is new. For object b, everything remains the same as object a, because it overrides the pqr of class yyy. Restoring back the defaults, lets look at the third line. Object c looks like www. In class www, pqr is a new and hence it has nothing to do with the earlier pqr functions. In class vvv, we are overriding the pqr of class www and hence the pqr of vvv gets called. Remove the override and then it will get called from class www. The object d thankfully follows none of the above rules as the left and the right of the equal to sign are the same data types. An override method is a method that has the override modifier included on it. This introduces a new implementation of a method. You cannot use the modifiers new, static or virtual along with override. However abstract is permitted.
a.cs class zzz { public static void Main() { yyy a = new xxx(); a.pqr(); yyy b = new www(); b.pqr(); } } class yyy { public virtual void pqr()

{ System.Console.WriteLine(yyy pqr); } } class xxx : yyy { public override void pqr() { base.pqr(); System.Console.WriteLine(xxx pqr); } } class www : xxx { public override void pqr() { base.pqr(); System.Console.WriteLine(www pqr); } } Output yyy pqr xxx pqr yyy pqr xxx pqr www pqr

Using the keyword base, we can access the base class functions. Here whether pqr is virtual or not, it is treated as non virtual by the keyword base. Thus the base class pqr will always be called. The object a knows that pqr is virtual. When it goes to yyy, it sees base.abc and hence it calls the pqr of yyy. In the second case, it first goes to class vvv, here it calls the base.abc, i.e. the function pqr of class xxx, which in turn calls function pqr in class yyy.
a.cs class zzz { public static void Main() { yyy a = new xxx(); a.pqr(); } } class yyy { public virtual void pqr() { System.Console.WriteLine(yyy pqr); } } class xxx : yyy { public override void pqr() { ((yyy)this).pqr(); System.Console.WriteLine(xxx pqr); } } Output

Unhandled Exception: StackOverflowException.

No amount of casting will stop the infinite loop. Thus even though this is being cast to a yyy, it will always call pqr from xxx and not yyy. Hence you see no output
a.cs class zzz { public static void Main() { yyy a = new www(); xxx b = new www(); a.pqr();a.xyz(); b.pqr();b.xyz(); } } class yyy { public virtual void pqr() { System.Console.WriteLine(yyy pqr); } public virtual void xyz() { System.Console.WriteLine(yyy xyz); } } class xxx : yyy { private new void pqr() { System.Console.WriteLine(xxx pqr); } public new void xyz() { System.Console.WriteLine(xxx xyz); } } class www : xxx { public override void pqr() { System.Console.WriteLine(www pqr); } public void xyz() { System.Console.WriteLine(www xyz); } } Output www pqr yyy xyz www pqr xxx xyz

More virtual functions, more complications in life. Let us embark on a thousand mile journey with a single step.

When we have a statement a.pqr, C# starts at the class yyy as usual, sees virtual, then goes to class xxx. Here pqr is private and hence its scope is limited to class xxx. The modifier new is thus ignored. C# now goes to class www where the pqr overrides the pqr of class yyy and thus we see www pqr. If we remove the override modifier from function pqr in class www, as it is a new function, it will now be called from class yyy. a.xyz calls pqr from yyy due to the explanation given many times before i.e. they are all news. b.pqr knows that pqr in class xxx is private. The scope of this pqr does not extend to class www, the derived class. As the pqr in class www overrides the pqr of class xxx, the one from class www gets called as it overrides the one from the base class yyy. If you change the override to new, then the pqr in www is a new one and has nothing to do with the one from yyy. This calls pqr from the base class yyy. b.xyz calls it from class xxx. This has already been explained at least a trillion times earlier.

Abstract Classes
a.cs public class zzz { public static void Main() { new aaa(); } } abstract class aaa { } Compiler Error a.cs(5,1): error CS0144: Cannot create an instance of the abstract class or interface aaa

The keyword abstract can be written before a class. It is called a class modifier. An abstract class cannot be instantiated by the keyword new. We cannot create an object that looks like aaa. Thus we cannot use the class and for all practical purposes the class is useless to us.
a.cs public class zzz { public static void Main() { new aaa(); }

10

Properties and Indexers Properties


Properties are a natural extension to fields. Very few programming languages support the notion of a property. Unlike a variable, a property is not stored in a memory location. It is made up of functions. Thus even though a property and a field share the same syntax a property has the advantage that code gets called. When we initialize a variable, no code in our class gets called. We are not able to execute any code for a variable access or initialization at all. In the case of a property, we can execute tons of code. This is one singular reason for the popularity of a product like Visual Basic - the use of properties. One simple example is setting the value of a variable. If it is through a variable, we have no control over the value used. If the same access is through a property, the programmer has no inkling of whether it is a property or a variable, we can build range checks to make sure that the variable does not cross certain bounds. Lets start by creating a simple property. A property is a member of a class. It behaves like a variable for the user.
a.cs public { public { } } public { public } }

class zzz static void Main()

class aa int ff {

Compiler Error a.cs(9,12): error CS0548: aa.ff : property or indexer must have at least one accessor

We have tried to create a property called ff which is of type int. We get an error because a property is used either on the left or the right of an equal to sign. If we had created a variable ff, we would like to write a statement as gg = ff + 9. Here ff should return some value which is of the data type int.
a.cs public class zzz { public static void Main() { aa a = new aa(); int gg = a.ff + 9; System.Console.WriteLine(gg); } } public class aa { public int ff { get { System.Console.WriteLine(in get); return 12;

} } } Output in get 21

A property should have at least one accessor, in our case, a get as we want to read the value of the property. Thus a.ff calls the get accessor which returns an int, in this case 12. If we did not have access to the code of the class aa, we would have assumed ff to have been a variable.
a.cs public class zzz { public static void Main() { aa a = new aa(); a.ff = 19; System.Console.WriteLine(a.ff); } } public class aa { public int ff { get { System.Console.WriteLine(in get); return 12; } set { System.Console.WriteLine(value); } } } Output 19 in get 12

A variable can also be used on the left-hand side of the equalto sign. In this case we are writing or changing the value of the variable. We are passing it some value. If it is a property, ff in our case, a.ff = 19 will call the accessor set. The set accessor has a free variable available in it called value. It gets created automatically, we do not create this variable. In our case, this has the value 19, which we are displaying in WriteLine. Then to display the value of the property ff, the get needs to be called again. The get always returns the same answer as the set does not store the value of the variable anywhere. To resolve this issue, we do the following.
a.cs public class zzz { public static void Main() { aa a = new aa(); a.ff = 19; System.Console.WriteLine(a.ff); }

} public class aa { int f1; public int ff { get { System.Console.WriteLine(in get); return f1; } set { System.Console.WriteLine(in set + value); f1 = value; } } } Output in set 19 in get 19

To implement a property in real life, we create a public variable which will hold the value of the property. This variable f1 will have the same data type as the property i.e. an int in our case. In the get, we return f1 and in the set we initialize f1 to value. This is the simplest case possible. The reason we use a property and not a variable is because if we change the value of a variable/field, then code in our class is not aware of the change. Also we have no control over what values the variable will contain. The user can change them to whatever he/she likes and we cannot implement range checks on the variable. Also the user may want to associate some action with the changes in the value of the variable. Using a property, reading or writing to the variable also can be monitored.
a.cs public class zzz { public static void Main() { aa a = new aa(); a.ff = 19; System.Console.WriteLine(a.ff); } } public class aa { int f1; public int ff { get { System.Console.WriteLine(in get); return f1; } } } Compiler Error a.cs(6,1): error CS0200: Property or indexer aa.ff cannot be assigned to it is read only

You are allowed to declare a property readonly by omitting the set accessor. No one is now allowed to change the value of the property. It now behaves as a const or readonly field.
a.cs public class zzz { public static void Main() { aa a = new aa(); a.ff = 19; } } public class aa { int f1; public int ff { set { System.Console.WriteLine(in set + value); f1 = value; } } } Output in set 19

Theoretically, you can have a property which is write only i.e. only with a set accessor. With set, you can change the value of ff but it is of limited use because you can never access the value of ff. A property differs from a field by ending with {}.
a.cs public { public { } } public { public class zzz static void Main()

class aa int ff { set { }

} public int ff { get { } } } Compiler Error a.cs(12,12): error CS0102: The class aa already contains a definition for ff

You cannot create a property in 2 separate bits and pieces. It has to be in one whole. This is part of the syntax. The above creates two properties, both called ff, the first one being write only, the second, read only. The compiler tells you that you cannot create two properties by the same name.

a.cs public class zzz { public static void Main() { } } public class aa { private int ff; public int ff { get { } set { } } } Compiler Error a.cs(10,12): error CS0102: The class aa already contains a definition for ff

You obviously cannot have a property and variable with the same name. The compiler would not know whether to invoke the property or the field. They both are stored in the same namespace.
a.cs class zzz { public static void Main() { yyy.i = 20; System.Console.WriteLine(yyy.i); } } class yyy { public static int i { get { System.Console.WriteLine(get); return 10; } set { System.Console.WriteLine(set + value); } } } Output set 20 get 10

The rules of static apply to properties also. Like variable we access them using the class and not the instance. Everything that we have learned about static in the past applies to properties also.
a.cs class zzz { public static void Main() {

yyy a = new yyy(); a.i = 100; System.Console.WriteLine(a.i); } } abstract class xxx { public abstract int i { get ; set ; } } class yyy : xxx { public override int i { get { System.Console.WriteLine(get); return 10; } set { System.Console.WriteLine(set + value); } } } Output set 100 get 10

The abstract property i in class xxx carries no code at all. The get and set accessors are simply represented by a semicolon. In the derived class, we must implement both the get and the set accessors. If we do not use the override keyword, it is new. We hope you have finally understood new and override.
a.cs class zzz { public static void Main() { } } abstract class xxx { public abstract int i { get ; } } class yyy : xxx { public override int i { get { } set {

} }

Compiler Error a.cs(20,1): error CS0546: yyy.i.set: cannot override because xxx.i does not have an overridable set accessor

In class xxx, the abstract property has only a get accessor. In the derived class we are implementing both the get and the set. The original never ever had a set. This is unacceptable to the compiler. Thus we have no choice but to implement only the accessors that are present in the original. A get accessor can be viewed as a method which returns a value but accepts no parameters.
a.cs class yyy { public void i { } } Compiler Error a.cs(3,13): error CS0547: i : property or indexer cannot have void type

It makes no sense for an accessor to have a void type as a variable cannot be of type void. Void literally means I do not know the type or no type at all.
a.cs class yyy { public int i { set { return 10; } } } Compiler Error a.cs(6,2): error CS0127: Since yyy.i.set returns void, a return keyword must not be followed by an object expression

A set accessor can be viewed as function which returns void but accepts one parameter which stands for the value of the property. Thus a set cannot return a value. If we remove the 10, we will not get an error.
a.cs class zzz { public static void Main() { } public int i { set { value = 20; } } }

The reserved variable value in the set can be changed at will. Though, understanding why anyone would want to do such dumb stuff is beyond us.
a.cs class zzz { public static void Main() { } public int i { set { int value; } } } Compiler Error a.cs(9,6): error CS0136: A local variable named value cannot be declared in this scope because it would give a different meaning to value, which is already used in a parent or current scope to denote something else

We cannot however create a variable value as it will clash with the variable value which is already present by default in the set.
a.cs class zzz { public static void Main() { yyy a = new yyy(); a.i = 10; xxx b = new xxx(); ((yyy)b).i = 20; b.i = 10; } } class yyy { public int i { set { } } } class xxx : yyy { public int i { get { return 10; } }} Compiler Error a.cs(9,1): error CS0200: Property or indexer xxx.i cannot be assigned to it is read only

In the class yyy, the property i has only the set accessor. In the class xxx which derives from yyy, we have implemented only the get accessor. The property i in class xxx hides the i of yyy. They do not add up. What we are trying to say is that both these properties are independent of each other. What we had thought C# would have done is, taken the set from one class and added it to the second. However, that does not make sense. It treats them independently. If we want to use the property of the class yyy, then

we need to explicitly cast it as we have done for b. Thus the property i of class yyy gets hidden but can be accessed. A property is not necessarily slower than a variable. A variable access normally initializes some memory, whereas a property executes a method. This is not necessarily slower as at times, C# will rewrite your property methods to memory accesses. This is called inlining of code. Except for minor differences, all that we mentioned about virtual, abstract and new apply also to a property. The difference is, if the original property has a get and a set, the derived class will only implement a set or a get.

Indexers
An indexer lets us access members of a class as if it were an array.
a.cs public class zzz { public static void Main() { yyy a = new yyy(); a[1] = 10; } } public class yyy { } Compiler Error a.cs(6,1): error CS0021: Cannot apply indexing with [] to an expression of type yyy

We have created an object a that looks like yyy. The object a, in no sense of the word is an array. We are assuming that a is an array and weve used the array syntax a[], hence it gives us an error.
a.cs public class zzz { public static void Main() { yyy a = new yyy(); a[1] = 10; } } public class yyy { public int this[int i] { set { System.Console.WriteLine(in get + value + + i); } } } Output in get 10 1

Weve added a few lines to have the array notation work with an object that looks like yyy. To implement indexers, we need to create a special property called this. This is a reserved word. As of now, we have a parameter i (an int) in the square brackets. When we did properties earlier,we learnt that a set gets called whenever we want to initialize or set a variable. Within the set accessor we have a special

variable called value which stores the value passed to the set, in this case 10. The variable i will hold the value 1 as the array parameter is 1. This is how we implement arrays when there are none.
a.cs public class zzz { public static void Main() { yyy a = new yyy(); System.Console.WriteLine(a[1]); } } public class yyy { public int this[int i] { set { System.Console.WriteLine(in get + value + + i); } get { System.Console.WriteLine(in set + i); return 23; } } } Output in set 1 23

The rules binding properties are applicabe to indexers too. When you want to read the value of a[1], the get gets called. The major difference between properties and indexers is that when you implement the code for indexers you have to understand that the get and set get called with a variable which is the array parameter value. The code will have to understand array simulation.
a.cs public class zzz { public static void Main() { yyy a = new yyy(); a[hi] = 30; System.Console.WriteLine(a[hi]); } } public class yyy { public int z; public int this[string i] { set { System.Console.WriteLine(in get + value + + i); z = value; } get

{ System.Console.WriteLine(in set + i); return z; } } } Output In get 30 hi In set hi 30

The this property has a return value, in this case, an int. Also the [] brackets can contain data types other than an int. In this case a string. The string i has a value hi as that is what we passed in the array brackets. You can have two thiss in your class. You have to decide what data type to use in the array brackets. An indexer is very useful when you have a database object and you want to access the data in the fields using a notation [fieldname] Indexers follow the same concepts of virtual, new, override etc.
a.cs class zzz { public static void Main() { yyy a = new yyy(); a[1] = 10; a[one] = 10; a[hi,2] = 30; } } class yyy { public int this [ int i] { set { System.Console.WriteLine(one int + i + + value); } } public int this [ string i] { set { System.Console.WriteLine(one string + i + + value); } } public int this [ string i, int j] { set { System.Console.WriteLine(one string and int + i + + j + + value); } } } Output one int 1 10 one string one 10 one string and int hi 2 30

The signature of an indexer is the number and types of formal parameters. The return value and the names of the parameters do not contribute to the indexers signature. Thus we have overloaded the indexers to take an int, string or a string int combination. Each time a different function gets called. The point to understand is that all the indexers have to return the same data type, in our case int. The same rules that apply to function overloading apply here also. Functions cannot differ only by return values. We are sure that for indexers in the next version, C# should/must make an exception. A property is identified by its name, an indexer by its signature. There is no concept of property overloading in C#.
a.cs class zzz { public static void Main() { } } class yyy { public static int this [ int i] { set { } } } Compiler Error a.cs(9,19): error CS0106: The modifier static is not valid for this item

A property can be both an instance member which is the default or static. An indexer unfortunately can only be an instance member and not static. God alone knows why this discrimination against indexers. Once again no rational reason for the above error. Obviously you cannot create a variable with the same name as that of the parameter passed in the indexer.
a.cs class zzz { public static void Main() { xxx a = new xxx(); a[2] = 20; System.Console.WriteLine(a[2]); } } class yyy { public virtual int this [ int i] { get { System.Console.WriteLine(yyy get + i); return 20; } set { System.Console.WriteLine(yyy set + value + + i); }

} } class xxx : yyy { public override int this [ int i] { get { int p = base[i]; System.Console.WriteLine(xxx get + i + + p); return 200; } set { System.Console.WriteLine(xxx set + value + + i); base[i] = value; } } } Output xxx set 20 2 yyy set 20 2 yyy get 2 xxx get 2 20 200

The above example deals with calling the indexers of the base class. At times when we are overriding code in the derived class, we would like to call the original indexer in the base class first. The first rule that we have to adhere to is that the indexer in the base class must be declared virtual. In the derived class, we are now declaring it with the modifier override. Same rules as above. In the set accessor, we have to call the original as base[i], where i is the index to the indexer. Also we need to pass it the value to initialize itself. This is stored in the variable value. This a[2] in Main gets replaced by base[2] in the set. In get the reverse takes place. Here we need to place base[i] on the right of the equalto sign, the original get will return a value, in this case 20, which we are storing in a variable p. What we do with p as well as the value from the get is our business.
a.cs class yyy { public int this [ byte i , string j] { get { return 10; } set { } } int get_Item(byte i,string j) { return 20 } void set_Item(byte i,string j , int value) { } }

Compiler Error a.cs(5,1): error CS0111: Class yyy already defines a member called get_Item with the same parameter types a.cs(9,1): error CS0111: Class yyy already defines a member called set_Item with the same parameter types Like a property, an indexer also gets a name change. If people can get their bodies pierced then why cannot a indexer get converted to a series of functions starting with get? For a get, the parameters are the same as we pass to an indexer. It has a return value and the type of the indexer. Also the set has one more added parameter and that is the free variable value.

11
Interfaces and Structures Constructors Revisited
A constructor is used to initialize the instance of a class as explained earlier.
a.cs public class zzz { public static void Main() { System.Console.WriteLine("in bb a = new bb(); bb b = new bb(10); } } public class aa { public aa() { System.Console.WriteLine("in } public aa(int i) { System.Console.WriteLine("in } } public class bb : aa { public bb() { System.Console.WriteLine("in } public bb(int i) { System.Console.WriteLine("in }

main");

const aa");

const aa" + i);

const bb");

const bb" + i);

} Output in main in const aa in const bb in const aa in const bb10

Class aa is the base class. It consists of two constructors. One that takes no parameters and the other that takes an int as a parameter. Class bb is derived from class aa, i.e. aa is the base class, bb the derived class. When we create an object like bb, the compiler does not execute the code for the constructor but instead asks the constructor which constructor of the base class to execute first. As we haven't stated this, by default, the constructor with no parameters get executed. Remember it is the base class constructor which gets executed first and the derived class constructor specifies which base class constructor to call first. In the second case, even though we are calling the constructor with a parameter, the constructor with no parameters in the base class gets called and not the one with one int as a parameter.

a.cs public class zzz { public static void Main() { System.Console.WriteLine("in bb a = new bb(); bb b = new bb(10); } } public class aa { public aa() { System.Console.WriteLine("in } public aa(int i) { System.Console.WriteLine("in } } public class bb : aa { public bb() : base() { System.Console.WriteLine("in } public bb(int i) : base(i) { System.Console.WriteLine("in } } Output in main in const aa in const bb

main");

const aa");

const aa" + i);

const bb");

const bb" + i);

in const aa10 in const bb10

If we do not specify which constructor of the base class to call, C# by default calls the constructor with no parameters. Which means that C# rewrites our code . When we write bb(), it gets rewritten as bb() : base(). Base is a reserved word. It means call the constructor of the base class with no parameters. For the second constructor, bb(int i), the line gets rewritten to bb(int i) : base(). We now want to call the constructor with one int and hence we write bb(int i) : base(i). That is why the constructor with one int gets called. We have the option to decide which constructor of the base class we would like to call.
a.cs public class zzz { public static void Main() { System.Console.WriteLine("in bb a = new bb(); } } public class aa { public aa() { System.Console.WriteLine("in } public aa(int i) { System.Console.WriteLine("in } } public class bb : aa { public bb() : this(20) { System.Console.WriteLine("in } public bb(int i) : base(i) { System.Console.WriteLine("in Output in main in const aa20 in const bb20 in const bb

main");

const aa");

const aa" + i);

const bb");

const bb" + i); } }

A constructor gets called at the time of creation of the object. At the line, new bb(), the compiler asks the constructor of bb as to which constructor of the base class aa to call. Here he was told that the answer lies with this(20). this, like base, is a reserved word. It means call a constructor of the same class and not the base class. Therefore the compiler now asks the one constructor of the derived class bb which constructor of the base class to call. bb(int i) : base(i) tells the compiler to execute the one int constructor of aa. This is the first constructor that gets called. Then the one int constructor of bb gets called and finally the one who started it all, the no parameter constructor of bb. Thus, two derived class constructors get called instead of one.
a.cs public class zzz { public static void Main() {

System.Console.WriteLine("in main"); aa a = new aa(); } } public class aa { private aa() { } } Compiler Error a.cs(6,8): error CS0122: 'aa.aa()' is inaccessible due to its protection level

When you create a constructor which is private, you cannot create an object that looks like aa. Thus aa should only contain static members.
a.cs public class zzz { public static void Main() { } } public class aa { private aa() { } } public class bb : aa { } Compiler Error a.cs(13,14): error CS0122: 'aa.aa()' is inaccessible due to its protection level

Nor can any class derive from aa. Thus no one can instantiate an object that looks like aa or derive from it as the constructor has been made private.
a.cs public class zzz { public static void Main() { System.Console.WriteLine(aa.i); } } public class aa { private aa() { } static public int i = 20; } Output 20

You can however use all the static variables in aa


a.cs public class zzz { public static void Main() { } } class yyy { public yyy() { } } class xxx : yyy { public int i; xxx() : base( this.i) { } } Compiler Error a.cs(16,15): error CS0027: Keyword this is not available in the current context

Base is called a constructor initializer. When base gets called, the instance or the object has not yet been created. Ergo, this is not available here as this refers to the current object. In the constructor, however, this can be freely used. The values of variables in a class are initialized to their default values as per their data types before the constructor gets called. Thus, in the constructor they have their default values as shown below.
a.cs public class zzz { public static void Main() { yyy a = new yyy(); } } class yyy { public int i; public bool j; public yyy() { System.Console.WriteLine(i+" " + j); } } Output 0 False

Here as before, the first line of code in the constructor gets executed.
a.cs public class zzz {

public static void Main() { xxx a = new xxx(); } } class yyy { public int i = 10; public yyy(int j) { System.Console.WriteLine(i); i = j; } } class xxx : yyy { public xxx() : base(100) { System.Console.WriteLine(base.i); } } Output 10 100

Calling the base class constructor is like inserting all the code of the one int constructor i.e. yyy(int j), in the constructor of class xxx. We are also allowed to access members of the base class after the constructor gets called. Also, first the variable i gets initialized to 10 or the default value of int. Then we change it to 100 and in the constructor of xxx, we will see a value of 100.
a.cs public class zzz { public static void Main() { xxx a = new xxx(); } } class yyy { public yyy() { abc(); } public virtual void abc() { } } class xxx : yyy { public int x = 10; public xxx() { System.Console.WriteLine(x); x = 100; System.Console.WriteLine(x); } public override void abc()

12
Operator Overloading
Lets explain what operator overloading is all about with an example of a class that represents a date. Would it not be great if we could subtract two date objects and be returned an int representing the number of days elapsing between the two dates. We would like to use the good old subtraction operator like we do when subtracting numbers. Also we would like the > operator to compare two date objects and tell us which one is larger. The + operator could add a number to a date resulting in a new date object. Thus, operator overloading lets us redefine the existing operators so that they work with classes/objects we create like yyy. We have not yet instructed C# on how to use the trusty old + operator with two yyy objects. Though C# knows how to use the + to add two numbers, it does not know how to add two yyys.
a.cs public class zzz { public static void Main() { yyy a = new yyy(10); yyy b = new yyy(5); yyy c; c=a+b; } } public class yyy { public int i; public yyy( int j) { i = j; } } Compiler Error a.cs(8,5): error CS0019: Operator + cannot be applied to operands of type yyy and yyy

We have created a simple class yyy which has one instance variable i which will distinguish different instances of yyy from each other. The constructor with an int as a parameter initializes i. We have tried to add two objects that look like yyy which does not go down well with C# and it objects to it.
a.cs public class zzz { public static void Main() { yyy a = new yyy(10);

yyy b = new yyy(5); yyy c; c=a+b; } } public class yyy { public int i; public yyy( int j) { i = j; } public yyy operator + ( yyy x , yyy y) { } } Compiler Error a.cs(18,12): error CS0558: User-defined operators yyy.operator +(yyy, yyy) must be declared static and public

Error messages can be at times helpful. Our operator + is public but not static. C# demands that all operator overloads be static.
a.cs public class zzz { public static void Main() { yyy a = new yyy(10); yyy b = new yyy(5); yyy c; c=a+b; System.Console.WriteLine(c.i); } } public class yyy { public int i; public yyy( int j) { i = j; } public static yyy operator + ( yyy x , yyy y) { System.Console.WriteLine(operator + + x.i + + y.i); yyy z = new yyy(x.i+y.i); return z; } } Output operator + 10 5 15

The word operator as the name of a function, is legal and the only way to overload operators. We follow this word with the operator we want to overload and then the parameters we will call the operator with. + is a binary operator and will need two yyys, one on its left and the other on its right. Then at beginning, we give the return value of the operator. In our case we want a + to add two yyys and return a third yyy whose i will be the sum of the individual is. Thus a+b will call the operator + with x being equal to a and y to b. Thus x.i will have a value 10 and y.i, 5. We are creating a new object z and in the

constructor passing 15 i.e. 10 + 5. Thus the i of z will be 15 which is being returned. a + b will now be replaced by the object whose i has a value 15 and c will be equal to this object. Thus c.i will be equal to 15.
a.cs public class zzz { public static void Main() { yyy a = new yyy(10); yyy b = new yyy(5); yyy c; c=a+b; System.Console.WriteLine(c.i); } } public class yyy { public int i; public yyy( int j) { i = j; } public static yyy operator = ( yyy x , yyy y) { } public static yyy operator + ( yyy x , yyy y) { System.Console.WriteLine(operator + + x.i + + y.i); yyy z = new yyy(x.i+y.i); return z; } } Compiler Error a.cs(19,28): error CS1020: Overloadable binary operator expected

The error message is telling us that we cannot overload the assignment operator =. Every class gets a free assignment operator which does a bitwise copy of the variables of the object from the left to the right.
a.cs public class zzz { public static void Main() { yyy a = new yyy(10); yyy b = new yyy(5); yyy c = new yyy(2); yyy d; d=a+b+c; System.Console.WriteLine(d.i); } } public class yyy { public int i; public yyy( int j) { i = j;

} public static yyy operator + ( yyy x , yyy y) { System.Console.WriteLine(operator + + x.i + + y.i); yyy z = new yyy(x.i+y.i); return z; } } Output Operator + 10 5 Operator + 15 2 17

The only change is d = a + b + c. C# gets easily confused with complex statements so it does not read all of it. It sees two operators on the same line. In this case, the same plus. An internal rule tells it to read the plus left to right i.e. it will only see a + b. It will call the operator + with x.i as 10 and y.i as 5 because as i is 10 and bs i is 5. This will create a temporary object like yyy whose i is 15, lets call it zz. The object z is very different from zz. C# then evaluates zz + c. Thus x.i will display 15 and y.i will have the value of c.i i.e. 2. To support multiple invocations of the operator on a single line, the code does not change.

13
Collection Objects
Earlier we used an array in a foreach. If the array had three members, the foreach got executed three times and each time the variable i had a different value. The concept described below is called a collection class. It is a class that returns a value each time till the values run out, thus making it easier for us to iterate through the array.
a.cs public class zzz { public static void Main() { yyy f = new yyy(); foreach (string i in f) { } } } class yyy { } Compiler Error a.cs(6,1): error CS1579: foreach statement cannot operate on variables of type yyy because yyy does not contain a definition for GetEnumerator, or it is inaccessible

To use yyy in a foreach as a collection class, foreach requires a function GetEnumerator.


a.cs public class zzz { public static void Main() { yyy f = new yyy(); foreach (string i in f) { } } } class yyy { public int GetEnumerator() { } } Compiler Error a.cs(6,1): error CS1579: foreach statement cannot operate on variables of type 'yyy' because 'int' does not contain a definition for 'MoveNext', or it is inaccessible a.cs(13,12): error CS0161: 'yyy.GetEnumerator()': not all code paths return a value

Foreach obviously tries to execute the function called GetEnumerator. This function should not return an int but something else as the error suggests.

a.cs using System.Collections; public class zzz { public static void Main() { yyy f = new yyy(); foreach (string i in f) { } } } class yyy { public IEnumerator GetEnumerator() { return new xxx(); } } class xxx : IEnumerator { } Compiler Error a.cs(19,7): error CS0535: xxx does not implement interface member System.Collections.IEnumerator.MoveNext() a.cs(19,7): error CS0535: xxx does not implement interface member System.Collections.IEnumerator.Reset()

a.cs(19,7): error CS0535: xxx does not implement interface member System.Collections.IEnumerator.Current

IEnumerator is an interface which has three functions MoveNext, Reset and Current and xxx has to implement all of them to remove the compiler errors.
a.cs using System.Collections; public class zzz { public static void Main() { yyy f = new yyy(); foreach (string i in f) { System.Console.WriteLine(i); } } } class yyy { public IEnumerator GetEnumerator() { return new xxx(); } } class xxx : IEnumerator { public bool MoveNext() { System.Console.WriteLine(MoveNext); return true; } public void Reset() { System.Console.WriteLine(Reset); } public object Current { get { System.Console.WriteLine(Current); return hi; } } }

Run the program and you will notice that the output does not stop. It goes on forever. IEnumerator is an interface which belongs to the namespace System.Collections. foreach first calls the function GetEnumerator from yyy. It expects this function to return an object like IEnumerator. It then calls the function MoveNext from this returned object. If MoveNext returns true it knows that there is some data to be read and it calls the property Current to access this data. From Current the get accessor gets called which always returns hi in our case. Then MoveNext gets called and if it returns false, we quit out of the foreach statement. As MoveNext always returns true, we go into an indefinite loop.
a.cs using System.Collections; public class zzz {

public static void Main() { yyy f = new yyy(); foreach (string i in f) { System.Console.WriteLine(i); } } } class yyy { public IEnumerator GetEnumerator() { return new xxx(); } } class xxx : IEnumerator { public string [] a = new string[3] {hi , bye ,no}; public int i = -1; public bool MoveNext() { i++; System.Console.WriteLine(MoveNext + i); if ( i == 3) return false; else return true; } public void Reset() { System.Console.WriteLine(Reset); } public object Current { get { System.Console.WriteLine(Current + a[i]); return a[i]; } } } Output MoveNext0 Current hi hi MoveNext1 Current bye bye MoveNext2 Current no no MoveNext3

We have created an array a which has 3 members and initialized them respectively to hi, bye and no by giving the strings in {} immediately after the new. Each time MoveNext gets called the variable i is increased by 1. If the value of i is 3, we have no more strings to return and thus we return false, else we return true. The variable i keeps track of how many times the function MoveNext is being called. As

MoveNext returns true, Current gets called which returns a string from the array using i as the offset. Thus we can iterate through the entire array depending upon the length.
a.cs using System.Collections; public class zzz { public static void Main() { yyy f = new yyy(This is Great); foreach (string i in f) { System.Console.WriteLine(i); } } } class yyy { string t; public yyy(string t1) { t = t1; } public IEnumerator GetEnumerator() { return new xxx(t); } } class xxx : IEnumerator { public string [] a; public xxx(string t3) { char [] b = new char[1]; b[0] = ; a = t3.Split(b); } public int i = -1; public bool MoveNext() { i++; System.Console.WriteLine(MoveNext + i); if ( i == a.Length) return false; else return true; } public void Reset() { System.Console.WriteLine(Reset); } public object Current { get { System.Console.WriteLine(Current + a[i]); return a[i]; } } }

Output MoveNext 0 Current This This MoveNext 1 Current is is MoveNext 2 Current Great Great MoveNext 3 Pretty big program. At the time of creating a yyy object we are passing a string to the constructor. Thus the yyy constructor gets called first. The constructor stores this string in variable t. The foreach statement calls GetEnumerator which now creates a xxx object passing it the string through t. The constructor of xxx now gets called. Every string class has a member function called Split. Split will break up a string on certain characters which we call delimiters. In this case, we want our string to be broken up whenever we encounter a space. The Split function requires an array of chars which it can use as a delimiter. The reason it requires an array is because we may have more than one char that we would like to break the string on. Like earlier, the array a now contains the array of strings. The last change is the condition in the if statement. Earlier we used a constant number, now we use a member, Length, of an array which stores the length of the array or the number of members. Thus the class yyy can now be used as a collection class which enumerates the individual words in the string. The function Reset for some reason never ever gets called.

14
Attributes, The Reflection API And Conditionals

Attributes
a.cs class zzz { public static void Main() { } } [vijay] class yyy { } Compiler Error a.cs(7,2): error CS0246: The type or namespace name 'vijay' could not be found (are you missing a using directive or an assembly reference?)

Anything in a square bracket is called an attribute. We tried to create an attribute called vijay, which C#, for some reason, does not seem to recognize.
a.cs

class zzz { public static void Main() { } } class vijay : System.Attribute { } [vijay] class yyy { }

All that we have done is created a class vijay that has been derived from the class System.Attribute and the error simply disappears. Thus an attribute is simply a class that derives from System.Attribute. To understand attributes lets take an example with structures.
a.cs class zzz { public static void Main() { yyy a = new yyy(); a.i = 65536+512+3; System.Console.WriteLine(a.i + " " + a.j + " " + a.k); } } struct yyy { public int i; public short j; public byte k; } Output 66051 0 0

A simple revision once again. We have created a structure a, that looks like yyy and initialized only one member i. Hence we see the warnings. The other members j and k get a default value of zero.
a.cs using System; class zzz { unsafe public static void Main() { Console.WriteLine(sizeof(byte) + " " + sizeof(short) + " " + sizeof(int) + " " + sizeof(long)); } } >csc a.cs Compiler Error a.cs(4,27): error CS0227: Unsafe code may only appear if compiling with /unsafe

The error here says that you have to use the /unsafe option while compiling any unsafe code.
>csc a.cs /unsafe

Output 1248

We shall explain the modifier unsafe in the next chapter. Sizeof tells us how much memory C# allocates for a data type. A byte is allocated one memory location, short 2, int 4 and a long 8.

a.cs using System.Runtime.InteropServices; class zzz { public static void Main() { yyy a = new yyy(); a.i = 65536+512+3; System.Console.WriteLine(a.i + + a.j + + a.k); } } [StructLayout(LayoutKind.Explicit)] struct yyy { [FieldOffset(0)] public int i; [FieldOffset(0)] public short j; [FieldOffset(0)] public byte k; } Output 66051 515 3

We are using an attribute StructLayout that belongs to the namespace System.Runtime.InteropServices. In the earlier program, we had used an attribute called vijay. Thus, StructLayout is a class derived from Attribute. We are passing a parameter LayoutKind.Explicit to it. The output now differs dramatically. Every variable is stored in memory. FieldOffset indicates the starting position of the variable within the memory location. Offset of 0 will position i, j, and k, all three variables at the same memory address of a. Explicit requires FieldOffset to be mentioned as we are explicitly laying the order for the variables held in the strucuture.LayoutKind.Sequential and LayoutKind.Auto gives different memory locations to each of the variable. We will explain the reasons a little later in the coming chapter Unsafe Code. We have seen how important attributes are so lets delve deeper into them.
a.cs class zzz { public static void Main() { } } class vijayAttribute : System.Attribute { } [vijay] class yyy { } [vijayAttribute] class yyy1 {

We are allowed a little leeway in the name of the attribute. By convention, the attribute class should end with the word Attribute and when we use the attribute, the name attribute is optional.
a.cs class zzz { public static void Main() { } } class vijay : System.Attribute { } [vijay("hi")] class yyy { } Compiler Error a.cs(10,2): error CS1501: No overload for method 'vijay' takes '1' arguments

We had used the attribute StructLayout earlier where we passed a parameter. When we do the same thing with our attribute vijay, we get the above error.
a.cs class zzz { public static void Main() { } } class vijay : System.Attribute { public vijay(string s) { } } [vijay("hi")] class yyy { }

We forgot to add a constructor that accepts a string as a parameter. If we had passed a number to our attribute vijay, we would have to create a constructor that accepts an int. Thus if we pass 2 parameters to vijay, we need the appropriate constructor.
a.cs class zzz { public static void Main() { } } class vijay : System.Attribute { public vijay(string s ,int i)

{ } } [vijay("hi",10,mukhi = 200)] class yyy { } Compiler Error a.cs(13,16): error CS0103: The name 'mukhi' does not exist in the class or namespace 'vijay'

What we tried to do is, take a word called mukhi and initialize it to 200. C# comes back and tells us that it does not know what mukhi is.
a.cs class zzz { public static void Main() { } } class vijay : System.Attribute { public vijay(string s ,int i) { } public int mukhi; } [vijay("hi",10,mukhi = 200)] class yyy { }

mukhi, now, is called a named parameter. It can also be termed as a property.


a.cs class zzz { public static void Main() { } } class vijay : System.Attribute { public vijay(string s ,int i) { } public int mukhi; public string sonal { get { return "ss"; } set { ; } } }

[vijay("hi",10, mukhi = 200, sonal = "bye")] class yyy { }

A named parameter is a non-static field or a non-readonly property. A positional parameter is what we pass on to a constructor. We have 2 positional parameters as our constructor has two parameters and mukhi and sonal are our named parameters. The named parameters come after the positional ones. The positional parameter's order is important, but the named parameters can be in any order. If we don't follow this rule we will get an error as follows.
Compiler Error a.cs(19,22): error CS1016: Named attribute argument expected

When we place the attribute before a function, the error disappears.


a.cs using System.Runtime.InteropServices; using System; class zzz { public static void Main() { } } [AttributeUsage(AttributeTargets.Class)] class vijay : System.Attribute { public vijay(string s ,int i) { } public int mukhi; public string sonal { get { return "ss"; } set { ; } } } class yyy { [vijay("hi",10, sonal = "bye",mukhi = 200 )] public void abc() {} } Compiler Error a.cs(24,2): error CS0592: Attribute 'vijay' is not valid on this declaration type. It is valid on 'class' declarations only.

AttributeUsage is one more attribute class derived from Attribute. It gives us the option to decide where the user can use the Attribute. The parameter in this case is class and hence we can use it only in front of a class and not in front of a method. The default is anywhere.

The Reflection API


Reflection or Introspection is when you look within to find out about your true self. In the same way we need a method by means of which, our program can find out all about a class. We need to know how many methods, properties etc while our program is executing or running. This distinction is important

and we could always read the documentation if we wanted to know more about the functionality of a class. But, C# gives us a large number of functions that tell us the innards of a class. These functions put together have to be used in a certain way. The functions have to be called in a certain order and the parameters to them have to conform to certain data types. This concept is called an API or a Application Program Interface. In short, an API is how a programmer uses functions to get a desired result.
a.cs using System; class zzz { public static void Main() { Type m; m = typeof(int); System.Console.WriteLine(m.Name + " " + m.FullName); m = typeof(System.Int32); System.Console.WriteLine(m.Name + " " + m.FullName); m = typeof(yyy); System.Console.WriteLine(m.Name + " " + m.FullName); } } class yyy { } Output Int32 System.Int32 Int32 System.Int32 yyy yyy

Typeof is a keyword. It needs a class name as a parameter. In the first case, we are specifying a class called int. typeof returns an object that looks like Type. This class has two members Name, which gives the name of the class and FullName which is the name preceded with the name of the Namespace. When we use int as the name of the class, the member Name does not display int but Int32; we mentioned earlier int is an alias for a structure Int32 in the System namespace. This is what FullName tells us. We thus have visible proof that int is an alias for a structure. yyy is class belonging to no namespace and hence the Name and FullName members are similar.
a.cs using System; using System.Reflection; class zzz { public static void Main() { Type m = typeof(yyy); MemberInfo [] n; n = m.GetMembers(); Console.WriteLine(n.Length); foreach ( MemberInfo a in n) { Console.WriteLine(a.Name); } } } class yyy { public void abc() {} private int pqr( int i ) { return 0;}

protected string xyz (string g , int p) {return "";} } Output 6 GetHashCode Equals ToString abc GetType .ctor

We are now displaying the members of a class yyy. The class Type has a function called GetMembers that returns an array of type MemberInfo. Every array has a field called Length that returns the size of the array. In our specific case it is 6. We then use a foreach to run through each member of the MemberInfo array and are displaying the name of each function using the field Name from the class MemberInfo.
a.cs using System; using System.Reflection; class zzz { public static void Main() { Type m = typeof(yyy); MemberInfo [] n; n = m.GetMembers(); Console.WriteLine(n.Length); foreach ( MemberInfo a in n) { Console.WriteLine((MemberInfo)a + " " + a.DeclaringType); } } } class yyy { public int i; public void abc() {} public int pqr( int i ) { return 0;} public string xyz (string g , int p) {return "";} } Output 9 Int32 i yyy Int32 GetHashCode() System.Object Boolean Equals(System.Object) System.Object System.String ToString() System.Object Void abc() yyy Int32 pqr(Int32) yyy System.String xyz(System.String, Int32) yyy System.Type GetType() System.Object Void .ctor() yyy

The first concept you need to be clear with is that we can inspect only details of public members and protected or private like pqr and xyz. Also variables are part of the members of a class. The MemberInfo object has a ToString function that displays the entire function in all its glory including parameters and their data types. The names of the parameter variables are however not being displayed. The DeclaringType member returns the class name that the member belongs to. Thus we can differentiate which class created the function.

Let us now display the attributes used on a class.


a.cs using System.Runtime.InteropServices; using System; using System.Reflection; class zzz { public static void Main() { Type m; m = typeof(yyy); System.Console.WriteLine(m.Name); foreach(object a in m.GetCustomAttributes (true)) Console.WriteLine(a); } } [AttributeUsage(AttributeTargets.All)] class vijay : System.Attribute { string s1,s2;int i1; public int mukhi; public override string ToString() { return s1+" " + s2+" " + i1 + " " + mukhi; } public vijay(string s ,int i) { s1=s;i1=i; } public string sonal { get { return s2; } set { s2 = value; } } } [vijay("hi1",10, sonal = "bye1",mukhi = 200 )] class yyy { [vijay("hi2",100, sonal = "bye2",mukhi = 2000 )] public void abc() {} [vijay("hi3",1000, sonal = "bye3",mukhi = 2 )] public int i; } Output yyy hi1 bye1 10 200

GetCustomAttributes takes a boolean as parameter and returns an array of objects. The ToString function of the attribute class gets called which will decide what string the attribute stands for.
a.cs using System.Runtime.InteropServices; using System; using System.Reflection; class zzz { public static void Main() {

Type m; m = typeof(yyy); System.Console.WriteLine(m.Name); foreach(MethodInfo a in m.GetMethods()) { object [] b = a.GetCustomAttributes(true); foreach(Attribute c in b) { Console.WriteLine(c); } } } } [AttributeUsage(AttributeTargets.All)] class vijay : System.Attribute { string s1,s2;int i1; public int mukhi; public override string ToString() { return s1+" " + s2+" " + i1 + " " + mukhi; } public vijay(string s ,int i) { s1=s;i1=i; } public string sonal { get { return s2; } set { s2 = value; } } } [vijay("hi1",10, sonal = "bye1",mukhi = 200 )] class yyy { [vijay("hi2",100, sonal = "bye2",mukhi = 2000 )] public void abc() {} [vijay("hi3",1000, sonal = "bye3",mukhi = 2 )] public void pqr() {} } Output yyy hi2 bye2 100 2000 hi3 bye3 1000 2

The object m looks like Type. As explained earlier, we are calling a function called GetMethods which returns an array of MethodInfo's. a loops through each one. We have two methods and the foreach gets executed twice. Once for abc and then for pqr. The GetCustomAttributes also exists in a MethodInfo class that returns an array of objects representing our attributes. We iterate through each, displaying what the ToString function returns. As we have only one attribute per function, the second for each gets executed only once.
a.cs using System.Runtime.InteropServices; using System; using System.Reflection; class zzz { public static void Main()

{ Type m; m = typeof(yyy); System.Console.WriteLine(m.Name); foreach(MethodInfo a in m.GetMethods()) { object [] b = a.GetCustomAttributes(true); foreach(Attribute c in b) { if ( c is vijay ) Console.WriteLine(c); } } } } [AttributeUsage(AttributeTargets.All)] class vijay : System.Attribute { string s1,s2;int i1; public int mukhi; public override string ToString() { return s1+" " + s2+" " + i1 + " " + mukhi; } public vijay(string s ,int i) { s1=s;i1=i; } public string sonal { get { return s2; } set { s2 = value; } } } [vijay("hi1",10, sonal = "bye1",mukhi = 200 )] class yyy { [vijay("hi2",100, sonal = "bye2",mukhi = 2000 )] public void abc() {} [vijay("hi3",1000, sonal = "bye3",mukhi = 2 )] public void pqr() {} }

There is no change at all in the output. A function can be decorated with as many attributes as you like. We would like to filter out certain attributes.
a.cs using System.Runtime.InteropServices; using System; using System.Reflection; class zzz { public static void Main() { Type m; m = typeof(yyy); System.Console.WriteLine(m.Name); foreach(MethodInfo a in m.GetMethods()) { object [] b = a.GetCustomAttributes(true);

foreach(Attribute c in b) { if ( c is vijay ) Console.WriteLine(c); } } } } class vijay : System.Attribute { public override string ToString() { return "vijay"; } } class vijay1 : System.Attribute { public override string ToString() { return "vijay"; } } class yyy { [vijay()] public void abc() {} [vijay()] [vijay1()] public void pqr() {} } Output yyy vijay vijay

We have two attribute classes vijay and vijay1. The function pqr has been decorated with 2 attributes whereas abc with only one. However we do not see vijay1 in the output as the 'c is vijay' makes the if statement true only for the attribute vijay and not vijay1. For the function pqr GetCustomAttributes returns an array of size two, but the if statement is true only for one of them, the one with the attribute name vijay. This is because of the 'is'.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); if ( a is yyy) Console.WriteLine("a yyy"); xxx b = new yyy(); if ( b is xxx) Console.WriteLine("b xxx"); if ( b is yyy) Console.WriteLine("b yyy"); int d = 10; if ( d is yyy) Console.WriteLine("b yyy"); }

} class xxx { } class yyy : xxx { } Output a yyy b xxx b yyy

We would like to know the data type of an object at runtime. C# offers you a keyword 'is' that lets you check the data type of an object. a looks like yyy and 'is' results in true. B looks like xxx but is initialized to a new yyy. Thus it doubles up for a yyy and a xxx resulting in the next two is's returning true. D is an int and not a yyy, so the last 'is' is false.

Attributes Revisited
Positional parameters are a must whereas names parameters are optional. Attribute parameters can be a bool, byte, char, short, int, long, float and double. These are the simple types that C# supports. Other data types are string, enums, objects arrays etc. Attribute usage has a position parameter which specifies the elements where the attribute can be used. The default is All. It also has one named parameter called AllowMultiple.
a.cs using System.Runtime.InteropServices; using System; class zzz { public static void Main() { } } [AttributeUsage(AttributeTargets.All)] class vijay : System.Attribute { public vijay(string s) { } } class yyy { [vijay("hi")][vijay("hi1")] public void abc() {} } Compiler Error a.cs(18,15): error CS0579: Duplicate 'vijay' attribute

By default we cannot use the same attribute twice on any entity.


a.cs using System.Runtime.InteropServices; using System;

class zzz { public static void Main() { } } [AttributeUsage(AttributeTargets.All,AllowMultiple=true)] class vijay : System.Attribute { public vijay(string s) { } } class yyy { [vijay("hi")][vijay("hi1")] [vijay("hi2") , vijay("hi3")] public void abc() {} }

We get no error as by default the AllowMultiple named parameter has a value of false. If we set its value to true, we are allowed to use multiple attributes on any entity. The above two forms are similar and either one can be used. Attribute permits us to set declarative information for various program entities for use by someone else at run time.

Conditionals
a.cs using System.Diagnostics; using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { [Conditional("vijay")] public void abc() { Console.WriteLine("abc"); } }

When we run the above program we get no output at all. In other words the function abc does not get called at all. This is inspite of writing a.abc().
a.cs #define vijay using System.Diagnostics; using System; class zzz { public static void Main() { yyy a = new yyy();

a.abc(); } } class yyy { [Conditional("vijay")] public void abc() { Console.WriteLine("abc"); } } Output abc

Any line beginning with a # is read by the C# pre-processor, a program that starts before the C# compiler starts. It has words like #define which creates a variable or word called vijay. In a programming language, a variable has to have a value, but in the preprocessor scheme of things, it may/maynot have a value. However if we do not give it a value, like in this case, the variable is only set to have been defined or created. Anything in [] brackets is an Attribute class. Earlier we had not created a variable vijay and hence the entire code of abc was left out of the executable file. Not only that, but all calls to function abc were eliminated from our code. All of this by defining or not defining a variable vijay. This is what we passed as the attribute to Conditional. We can create functions that are omitted during compilation depending upon a preprocessing symbol. When we write code, we add a lot of code for debugging purposes. This code is to help the programmer debug code. After a function works, it is error free, we do not require any of this debugging code. One way to eliminate this debugging code is by making the functions conditional. The resulting code is called a 'Retail build' and the debugging version, obviously a 'Debug build'. A Retail build is much smaller in size and obviously much faster. The #define has to be at the start of code. Another way of achieving the same result is by eliminating the #define from the code and creating a preprocessor symbol as an option to the compiler.
>csc a.cs /d:vijay

The compiler option is /d and the colon is part of the syntax. Following the colon is the name of the preprocessor symbol. In this case, it is vijay. Weve discussed preprocessors in one of the earlier chapters.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { [Obsolete] public void abc() { Console.WriteLine("abc"); } }

Compiler Error a.cs(7,1): warning CS0612: 'yyy.abc()' is obsolete Output abc Many a times we create functions in a class which we would not want the user to use, as these functions were useful years ago, but are now obsolete. The only way to warn the user that some time in the future we will no longer support these functions is by marking them with the attribute Obsolete. We see the warning as displayed above but the program runs as normal.

15
Unsafe code
Today, the programming language C is the most widely used because of only one reason and that is the use of pointers. In this chapter, we will explain what pointers are all about and how they can be used in the world of C#.
a.cs class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { public void abc() { int *i; } } Compiler Error a.cs(13,6): error CS0214: Pointers may only be used in an unsafe context

All simple variables like int, byte, short store numbers. When we create a variable in C#, we are allowed to put a multiplication/asterisk sign '*' in front of the variable. These variables are called Pointers. We get an error as C# considers pointers to be unsafe and hence we need special permission to use pointers.
a.cs class zzz { public static void Main() {

yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { int *i; } } Compiler Error a.cs(11,20): error CS0227: Unsafe code may only appear if compiling with /unsafe

As seen in the previous chapter, the unsafe option must be tagged while compiling the program. Give the command as csc a.cs /unsafe and the error now disappears.
a.cs class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } unsafe class yyy { public void abc() { int *i; } }

The C# documentation very clearly states that the modifier can be used along with the class keyword, By using the modifier unsafe, we are asking C# to let us use pointers as we are unable to write code without the use of pointers.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { Console.WriteLine(sizeof(byte *) + " " + sizeof(short *) + " " + sizeof(int *) + " " + sizeof(long *)); Console.WriteLine(sizeof(byte **) + " " + sizeof(short **) + " " + sizeof(int **) + " " + sizeof(long **)); } }

Output 4444 4444

Some time back, we had used the sizeof keyword, to determine how much memory C# allocates for our variables. When we ask for the sizeof an pointer variable, we always get 4, irrespective of whether the data type is a short or int or whatever, including another pointer.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { int *i; int j=1; i = &j; Console.WriteLine((int)i); *i = 10; Console.WriteLine(j); } } Output 1243472 10

We have created a variable j that has been initialized to one. We have also created a variable i, with a multiplication sign at the time of creation. By doing this C# allocated four memory locations to store i. What is most important is that a pointer variable is just like any another variable. It simply stores numbers. The single big difference is that a pointer variable value is interpreted as a computer memory location. If both i and j were being initialized to 1, then j is the number 1 as we know it, whereas i stand for computer memory location 1. Pointers can only be initialized to a computer memory location. Whenever we place an ampersand(&) in front of a variable, we are asking C# to tell us about the memory allocated for the variable. Every time C# creates a variable, it stores it somewhere in memory. We are at times interested in knowing where in memory the variable was allocated. A & in front of j will tell us the memory location where j starts in memory. As it is a computer memory location or address we can store it in i. C# allocated 4 memory location for j and the start of these 4 are being stored in a pointer. We would like to display the value of the pointer. The WriteLine function does not have an overload to display a pointer and we have to cast it to an int. As we get 1243472 displayed, it could only mean that the variable j begins here and is spread over memory locations 1243473, 1243474 and 1243475. We can only place the multiplication sign in front of a variable defined to be a pointer. If i is not a pointer, *i will return an error. C# here asks a simple question. What is the value of the variable i? . The answer is 1243472. C# will now go to memory location 1243472 to 1243475 and place the value 10 there. As the value of j is determined by what is present from memory locations 1243472 to 1243475, the value of j changes from 1 to 10.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { int *i; int j=1, k = 1; i = &j; Console.WriteLine((int)i); *i = 10; Console.WriteLine(j); i = &k; Console.WriteLine((int)i); *i = 100; Console.WriteLine(k + " " + j); } } Output 1243468 10 1243464 100 10

Whenever we create a pointer variable, int *i, we are not stating explicitly which int i will be pointing to. Thus it can point to one int today, another int tomorrow. This is what gives pointers their flexibility. It can point to any int it wants to in memory. We are first initializing i to point to j, then we are changing the value of j to 10 through the pointer. Then i points to k in memory, and then k's value is indirectly being changed to 100 through the pointer. The first WriteLine tells us that the variable j begins at memory location 1243468. From here the next 4 have been reserved for the variable j. Memory for k has

been allocated at 1243464. Thus, physically, k starts first in memory from 1243464 to 67 and j from 1243468 onwards.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { int *i; int j=1; i = &j; Console.WriteLine((int)i + " " + (int) &i); } } Output 1243464 1243468

Lets not forget that pointers are also variables and C# allocates memory for i. An & in front of any variable tells us where it starts in memory. Thus i starts from memory location 1243468 onwards.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { long *i; long j=1, k = 1; i = &j; Console.WriteLine((int)i); i = &k; Console.WriteLine((int)i); } } Output 1243460 1243468

The sizeof a long is 8 bytes and the addresses printed differ by 8 bytes.
a.cs

using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc(){ byte *i; byte j=1, k = 1; i = &j; Console.WriteLine((int)i); i = &k; Console.WriteLine((int)i); } } Output 1243468 1243472

The only change here is that j and k are not longs but bytes. Why are we learning all about pointers is a question you should ask yourself. The C# documentation says very clearly that a byte occupies one memory location. The sizeof byte will also return one. In the above output, however, the memory locations differ by 4. The reason being that on the Pentium Processor, if we want one memory location, we will receive a minimum of 4. That's why, the Pentium is said to be a 32-bit processor. It will give you memory in chunks of 4. From this knowledge, using a byte instead of a int does not conserve memory or speed up your program. The above explanation cannot be comprehended without the knowledge of pointers.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { byte *i; i = 0; Console.WriteLine((int)i); } } Compiler Error a.cs(15,5): error CS0029: Cannot implicitly convert type 'int' to 'byte*'

C# is a strongly typed language and we are not allowed to convert a zero which is an int to a byte *, the data type of i. The only way out is to use a cast.
a.cs using System;

class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { byte *i;char *j;int *k;long *l; i = (byte *)0; j = (char *)0; k = (int *)0 ; l = (long *)0; Console.WriteLine((int)i + " " + (int) j + " " + (int) k + " " + (int)l); i++;j++;k++;l++; Console.WriteLine((int)i + " " + (int) j + " " + (int) k + " " + (int)l); i++;j++;k++;l++; Console.WriteLine((int)i + " " + (int) j + " " + (int) k + " " + (int)l); } } Output 0000 1248 2 4 8 16

A pointer to any data type is allocated four memory locations at the time of creation. This enables pointers to store values that range from 0 to 4 billion. The question that comes to your mind, is what is the difference between a pointer to an int from a pointer to a long. We have created four variables i, j, k, l. Each is a pointer to a different data type. We have also initialized each variable to 0 and displayed their values using the WriteLine function. We have then incremented each of them by 1. To our surprise the pointer to an int k, increases by 4 and not by 1. The char pointer increases by 2 and long by 8. To make sure that is not a isolated phenomena, we increment them again. Same answer once again. They do not increase by one but by the size of the data type they point to. The sizeof a long is 8 and thus a pointer to a long increases by 8 and not 1. When we initialized l to zero, we were telling C# that a long begins at memory location 0. This long will occupy the next 8 memory locations, form 0 to 7. Thus when we write l++, we are telling C# to take us to the next long in memory, which has to begins now at 8. The first difference between pointers to different data types is that the amount the pointer value increases is dependent upon what it is pointing to.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void pqr(int x , int y , int z) { int *p1; int *p2; int *p3; p1 = &x; p2 = &y ; p3 = &z;

Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); *p1 = 20; *p2 = 30; } unsafe public void abc() { int *i ; int *j ; int *k; int l=1,m=2,n=3; i=&l; j=&m; k=&n; Console.WriteLine((int) i + " " + (int) j + " " + (int) k); pqr(l,m,n); Console.WriteLine(l + " " + m + " " + n); }} Output 1243460 1243456 1243452 1243424 1243436 1243432 123

We have created a variable i of type int in memory. It begins at memory location 1243460. Similarly m and n start at 56 and 52 respectively. We are then calling a function pqr and passing three parameters to it. These are being stored at memory locations 1243424, 36 and 32 respectively. When we write *p1, we are going to memory location 1243424 and writing 20 there. This will change the value of x from 1 to 20. As variable l begins at 1243460, its value remains unchanged. The area of memory where x, y and z start is called the stack. Stack memory is used to pass parameters to functions.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void pqr(int x , int y , int z) { int *p1; int *p2; int *p3; p1 = &x; p2 = &y ; p3 = &z; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); } unsafe public void xyz(int x , int y , int z) { int *p1; int *p2; int *p3; p1 = &x; p2 = &y ; p3 = &z; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); } unsafe public void abc() { int *i ; int *j ; int *k; int l=1,m=2,n=3; i=&l; j=&m; k=&n; Console.WriteLine((int) i + " " + (int) j + " " + (int) k); pqr(l,m,n); xyz(l,m,n); } } Output

1243460 1243456 1243452 1243424 1243436 1243432 1243424 1243436 1243432

Now you will begin to comprehend the importance of pointers. Its is an understanding of pointers that will give you a better insight into understanding the innards of a programming language. The last two WriteLines display the same answer as the stack memory gets reused for every function call. The stack is an area of memory that will store parameters and variables created in a function. Let us assume that the stack begins at memory location 100. The parameters are first pushed onto the stack and then all the local variables are created later, but below the parameters. Remember that the stack grows down in memory. When the function is over, the stack is moved back to 100, and the next function that gets called, reuses the same memory from 100. Thus anything created in a function has a lifetime of the open and close braces as the next function uses the same memory and the earlier values get overwritten.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void xyz() { int i=0,j=0,k=0; int *p1; int *p2; int *p3; p1 = &i; p2 = &j ; p3 = &k; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); } unsafe public void aaa() { int x=0,y=0,z=0; int *p1; int *p2; int *p3; p1 = &x; p2 = &y ; p3 = &z; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); } unsafe public void pqr() { int i=0,j=0,k=0; int *p1; int *p2; int *p3; p1 = &i; p2 = &j ; p3 = &k; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); } unsafe public void abc() { pqr(); xyz(); aaa(); } } Output 1243460 1243464 1243468 1243460 1243464 1243468 1243460 1243464 1243468

The above program proves a number of points. C# reuses the same memory for passing parameters and creating variables in functions. The variable names are not important as they get created on the stack, at the same place in memory.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void pqr(int x , int y , int z) { int *p1; int *p2; int *p3; p1 = &x; p2 = &y ; p3 = &z; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); p3++;p3++;p3++;p3++;p3++;p3++; Console.WriteLine((int) p3); *p3=20; p3++; Console.WriteLine((int) p3); *p3=200; } unsafe public void abc() { int *i ; int *j ; int *k; int l=1,m=2,n=3; i=&l; j=&m; k=&n; Console.WriteLine((int) i + " " + (int) j + " " + (int) k); pqr(l,m,n); Console.WriteLine(l + " " + m + " " + n); } } Output 1243460 1243456 1243452 1243424 1243436 1243432 1243452 1243456 1 200 20

Pointers are really unsafe. There is a simple rule in C# which says that variables created in one function abc, cannot be changed by another function pqr. The variables m and n begin at memory locations 1243456 1243452 respectively. If there was some way, I could write to these memory locations, I would be changing the values of m and n respectively. The pointer p3 stores, where the parameter z is stored in memory i.e. 1243432. If we can increment this pointer 6 times, 6 will actually be 24 due to pointer arithmetic, the value of p will now be 1243452 which is the address of n in memory. Thus from one function, I can change the value of another variable. In this case we are doing it on purpose but if I called a function, where a pointer went haywire, my variables change and nobody knows why the program stops working. Thus pointers are like a sharp knife, it can save a life in the hands of a doctor but in the wrong hands it can also kill.
a.cs

using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void pqr(int x , int y , int z) { int *p1; int *p2; int *p3; p1 = &x; p2 = &y ; p3 = &z; Console.WriteLine((int) p1 + " " + (int) p2 + " " + (int) p3); int q = 1; while ( q <= 12 ) { p1++; Console.WriteLine((int) p1 + " " + *p1); q++; } } unsafe public void abc() { int *i ; int *j ; int *k; int l=1,m=2,n=3; i=&l; j=&m; k=&n; Console.WriteLine((int) i + " " + (int) j + " " + (int) k); pqr(l,m,n); Console.WriteLine(l + " " + m + " " + n); } } Output 1243460 1243456 1243452 1243424 1243436 1243432 1243428 47645012 1243432 3 1243436 2 1243440 0 1243444 1243508 1243448 1243544 1243452 3 1243456 2 1243460 1 1243464 1243452 1243468 1243460 1243472 1243484 123

Would it not be a great idea to be able to display whatever is there on the stack. Between variables there are some gaps and the above program is displaying the contents of the stack. The variable q makes the loop go on 12 times and each time we increment p1 by 4. P1 is pointing to x the first parameter on the stack. Would it not aid understanding if Microsoft explained what all it pushes on the stack. One of the most common hacking exploits on the net is called a stack overflow.
a.cs using System;

class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } public class yyy { unsafe public void pqr( int *a) { Console.WriteLine("{0} {1} {2}",a[0],a[1],a[2]); } unsafe public void abc() { int [] a = new int[3]; a[0] = 10; a[1] = 2; a[2] = 30; pqr(a); } } Compiler Error a.cs(20,1): error CS1502: The best overloaded method match for 'yyy.pqr(int*)' has some invalid arguments a.cs(20,5): error CS1503: Argument '1': cannot convert from 'int[]' to 'int*'

We were trying to pass an array as a parameter to a function. Unfortunately C# has some other views.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } public class yyy { unsafe public void pqr( int *a) { Console.WriteLine("{0} {1} {2}",a[0],a[1],a[2]); } unsafe public void abc() { int [] a = new int[3]; a[0] = 10; a[1] = 2; a[2] = 30; fixed ( int *i = a) pqr(i); } } Output 10 2 30

The keyword fixed removed the error. An array in memory can be moved around by C#. We would like C# to keep it fixed in memory. The keyword fixed guarantees that C# will not move it around in RAM for the duration of the program. The only reason C# moves objects in memory is to speed up execution

of the program. The keyword fixed as part of syntax wants the () .Within them you can create a variable in our case i which we initialize to a C# object, an array a. The scope or lifetime of this array is in the next statement i.e. the invocation of function pqr. In case you have more lines you can use the {}. Even though a now is a pointer to an int, the notation a[0] refers to the first member. The name of an array tells us where the array starts in memory.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } public class yyy { unsafe public void pqr( int *a) { Console.WriteLine("{0} {1} {2}",a[0],a[1],a[2]); a[0] = 100 ; a[1] = 40; *(a+2) = 33; } unsafe public void abc() { int [] a = new int[3]; a[0] = 10; a[1] = 2; a[2] = 30; fixed ( int *i = a) pqr(i); Console.WriteLine("{0} {1} {2}",a[0],a[1],a[2]); } } Output 10 2 30 100 40 33

Changing anything through a pointer changes the original. Whenever we write a[1]= , we are changing the first member of the original array. a[1] is only a notation, it actually get converted to *(a+1). Thus we are changing the original members of the array. Also the array grows upward in memory.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } public class yyy { unsafe public void pqr( int *a) { Console.WriteLine("{0} {1} {2}",a[0],a[1],a[2]); for ( int i = 0 ; i<= 2000; i++) *(a+i) = i*10; } unsafe public void abc() { int [] a = new int[3];

a[0] = 10; a[1] = 2; a[2] = 30; fixed ( int *i = a) pqr(i); Console.WriteLine("{0} {1} {2}",a[0],a[1],a[2]); } }

Please do not run the above program as the error would be unpredictable. The reason being that we are writing beyond the bounds of the array. The array a created in the function abc has only 12 memory locations allocated for it. We are writing the next 2000 * 4, 8000 memory locations. The error on your machine will be very different form another machine. This unpredictability is why pointer errors are hard to catch, and your boss would thus not like you to use a pointer while programming.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } struct aaa { public int i,j; } class yyy { unsafe public void abc() { aaa *a;aaa b; b = new aaa(); a = (aaa *)b; } } Compiler Error a.cs(20,10): error CS0030: Cannot convert type 'aaa' to 'aaa*'

aaa is a structure with two members i and j. new aaa() allocates memory for i and j. new aaa() and b are of the same data type ie aaa. When we try to equate a and b, C# canot convert a pointer to a struct/class to the object itself. Remember new returns not a pointer to an object but the object itself.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } struct aaa { public int i,j; } class yyy {

unsafe public void abc() { aaa *a;aaa b; b = new aaa(); a = &b; int *x; x = &(a->i); int *y; y = &(a->j); Console.WriteLine((int) a + " " + (int)x + " " + (int) y); } } Output 1243468 1243468 1243472

We need to take the address of where b begins in memory by using the & and equate that to a. The address of an object like aaa is of the data type aaa *. As a now is a pointer to a structure, we have to use a different syntax to display the members of the structure. The new way is to use the -> operator. Thus a>i refers to the member i of the structure that looks like aaa. The variable x now stores the address of where the first member i begins in memory. Obviously the address of the first member i and the address of the structure will be the same and the second member will be stored 4 later.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } struct aaa { public int i,j; } class yyy { unsafe public void abc() { aaa *a;aaa b; b = new aaa(); a = &b; Console.WriteLine((int) a); b = new aaa(); a = &b; Console.WriteLine((int) a); } } Output 1243468 1243468

We have one object b that we have initialized twice with new. Each time we get the same memory location as the address of b in memory will remain the same.

Unions

a.cs using System.Runtime.InteropServices; class zzz { unsafe public static void Main() { yyy a = new yyy(); a.i = 65536+512+3; System.Console.WriteLine(a.i + " " + a.j + " " + a.k); int *i1;short *j1;byte *k1; i1 = &a.i; j1 = &a.j ; k1 = &a.k; System.Console.WriteLine((int)i1 + " " + (int) j1 + " " + (int) k1); System.Console.WriteLine(sizeof(yyy)); } } [StructLayout(LayoutKind.Explicit)] struct yyy { [FieldOffset(0)] public int i; [FieldOffset(0)] public short j; [FieldOffset(0)] public byte k; } Output 66051 515 3 1243476 1243476 1243476 4

Let us understand what a union is all about. We are printing the addresses of i, j and k and lo and behold they are all the same. In a union all the members begin at the same place and that is why their addresses were similar. If we understand pointers, understanding unions then becomes a piece of cake as we can visually see the addresses.
a.cs using System.Runtime.InteropServices; class zzz { unsafe public static void Main() { yyy a = new yyy(); a.i = 65536+512+3; System.Console.WriteLine(a.i + " " + a.j + " " + a.k); int *i1;short *j1;byte *k1; i1 = &a.i; j1 = &a.j ; k1 = &a.k; System.Console.WriteLine((int)i1 + " " + (int) j1 + " " + (int) k1); System.Console.WriteLine(sizeof(yyy)); } }

[StructLayout(LayoutKind.Explicit)] struct yyy { [FieldOffset(0)] public int i; [FieldOffset(0)] public short j; [FieldOffset(10)] public byte k; } Output 66051 515 0 1243468 1243468 1243478 11 a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { short i = 512+3; byte *j; j = (byte *)&i; Console.WriteLine((int)j + " " + i ); *j = 1; Console.WriteLine(i); j++; Console.WriteLine((int)j); *j=1; Console.WriteLine(i); j++; Console.WriteLine((int)j); *j=10; Console.WriteLine(i); } } Output 1243468 515 513 1243469 257 1243470 257

j is a pointer to a byte. From the output, we can see that i begins at 1243468. i is of data type short which means it takes 2 bytes. j now contains the the address value of i i.e. 1243468. The first line proves it. The statement *j=1 will change the bottom byte value to 1.j++ will then increment the address value by 1, hence *j=1 will now change the top byte to 1. The last j++ has no effect because the scope of short is only 2 btes. Hence we see no change in the value of i. Here, in place of the data type short, we have given an int.
a.cs using System; class zzz { public static void Main() { yyy a = new yyy(); a.abc(); } } class yyy { unsafe public void abc() { int i = 512+3; byte *j; j = (byte *)&i; Console.WriteLine((int)j + " " + i ); *j = 1; Console.WriteLine(i); j++; Console.WriteLine((int)j); *j=1; Console.WriteLine(i); j++; Console.WriteLine((int)j); *j=10; Console.WriteLine(i); } }

Output 1243468 515 513 1243469 257 1243470 655617

The last j++ in the series will touch the third byte, there by replacing the 1 to 10. Hence the output changes dramatically.

------------------------------------------------------------------------------------------------------------------Classes and Object Model in .NET We will start with an introduction to what is object oriented programming, how to write simple classes, creating objects etc. What is a 'class' ? In modern object oriented programming, large computer programs are divided into several 'classes'. Typically, a large project will have several hundred classes. A class represents an entity in a program. For example, if you are doing a small program called calculator, you will typically have a single (or more) class called 'Calculator' (you can give any name for your class). The class will have several 'methods', that will do the functionality of the class. So, your calculator may have methods like the following: Add() Subtract() Multiply() Divide() Here is a sample calculator class, written in C# : using System; public class Calculator { public int Add(int value1, int value2) { return value1 + value2; } public int Subtract(int value1, int value2) {

return value1 - value2; } public int Multiply(int value1, int value2) { return value1 * value2; } public int Divide(int value1, int value2) { return value1 / value2; }

Classes and objects [To be added.] Object model in .NET ------------------------------------------------------------------------------------------------------------------------------Property in C# class How do you access member variables of any class from outside the class ? In most of the languages including C+ + , you will make the member variables public so that you can create an instance of the class and directly access the public fields, as shown below: public class Car { // private fields. public string color; // constructor public Car() { } } The above class has one public field : color. You may access this field from outside the class as shown below: Car car = new Car(); car.color = "red"; string color = car.color; But this is the old way ! This would still work with C#, but the suggested approach is to use "Property" instead of directly accessing member variables. The following code snippet shows how to create "Property" in a class. public class Car { // private fields. private string color; // constructor public Car() { } public string Color { get

{ return color; } set { color = value; // save value into private field. } } } The above class has one private field - color. Then we have one "Property" called 'Color', which is used to represent the private field. Note that the field is private and the Property is public. (We have used the same name with upper/lower case to represent the 'Property' and 'field', but you may give any name you want.) Each property has two parts : get set The get part is executed when you access the value of the Property as shown below: Car car = new Car(); string color = car.Color; When executed, the above get accessor will return the value stored in the field 'color'. The set part is executed when you assign a value to the Property as shown below: Car car = new Car(); car.Color = "RED"; When executed, the above set accessor will assign the value "RED" to the private field 'color'. (Note that 'value' is a keyword, which will have the value assigned to it.) So, what is the difference ? On the first look, there is no difference! You can achieve the same behaviour by writing 2 different methods ( like SetColor(...), GetColor() ). First advantage of using property is, code looks cleaner than having 2 separate methods. You can simply call a property as if it was a field in the class. Well, then you may ask why make it 2 methods, we can make it a public field, so that we can access it by creating an instance of the class. The main advantage over using a Property instead of a public field is, with the property, you will get a chance to write few lines of code (if you want) in the get and set accessors. So, you can perform some validation or any other logic before returning any values or assigning to the private field. See the modifed class below: public class Car { // private fields. private string color; // constructor public Car() { } public string Color { get { if ( color == "" ) // return the value from privte field.

return "GREEN"; else return color; } set { if ( value == "" ) thrown new Exception ("Wrong value."); else color = value; } } } Let us analyze the get part first. Here we are checking whether there is a valid value in the field 'color' before we return the value. If it is empty, we are getting a chance to return a default value 'Green'. This way, we can make sure that whoever calls the property 'Color' will always get a valid color, never an empty string. In the set part, we are doing a validation to make sure we always assign a a valid value to our field. If someone assign an empty string to the 'Color' property, he will get an exception (error). Car car = new Car(); car.Color = ""; The above code will throw an error because we are trying to assign an empty string and the set accessor will throw an error if it an empty string. This way, we can make sure that we allow only valid values to be assigned. So, i guess now you would appreciate the purpose of "Property". So, no more public fields! Always have private fields and write public properties as wrapper for them if required to expose them to outside the class Namespaces in .NET A Namespace is a group of related classes. It is a good practice to group related classes into a namespace when you create a class library. The main advantage of using namespaces is, to avoid conflicts when you have multiple classes with the same name. For example, .NET comes with a class called 'Form'. Suppose you also write another class called 'Form' in your application and if you refer to the class 'Form', how does the compiler know which Form you are refering to ? Here is the importance of 'namespace'. You can refer to the .NET Form using the fully qualified name, including the namespace like this : System.Windows.Forms.Form And you can refer to your own Form like this : MyApplication.Form, where MyApplication is your namespace. So, namespaces allow you to avoid name conflicts! All classes in .NET class library are grouped into namespaces. You can use all the classes using the fully qualified name, including the namespace also along with the class name. System.Windows.Forms.Form System.String System.Double

If you want to declare a Button object, you must do the following : System.Windows.Forms.Button myButton; It is not mandatory to use the namespace also along with the name. You may use the using directive on top of the class and safely avoid the need to write the fully qualified name everytime when you refer to a class.

using System.Windows.Forms.Button; If you have the above line of code on top of the class file, you don't need to type the namespace name System.Windows.Forms with all the classes in this namespace. You can simply use class name directly as shown below: Button myButton; .NET Namespaces Here is a list of some of the namespaces in .NET class library. System System.Xml System.Data System.Data.OleDb System.Data.SqlClient

Windows Programming using C# WinForms WinForms is the most commonly used feature of .net. 'Windows' based applications in .net is called 'WinForms'. The .net framework comes with a good number of classes to support 'Form' based application development. A WinForm application will have atleast one 'Form' (window), which would be used for the interaction between the application and user. A Form can contain other controls like TextBox, Label, Button etc. Large WinForms applications will have several 'Forms', some of them used to capture data from user and some of them used to display data to user. By performing certain actions in each form, user can navigate to other 'Forms' in the application. Event driven programming Event Driven programming model is the most commonly used feature in modern programming. In this model, you will write appropriate code for each event. Examples for events are Button Click Mouse Move Mouse Click Key Press In Winforms application, users interact with the application using various actions in the window (like clicking a button, moving mouse, pressing keys in keyboard etc). These actions will generate various events. When an event is generated, the code written for that event will be executed. For example, in a user registration screen, you may have several controls like text boxes where user can enter their name, address, age etc. Once user enter all the information, he may press the 'Submit' button. As a developer, you would have written code in the button click event, to save this user entered data into a database. This is how typically a WinForms based application works in an event driven programming model. To create WinForms applications: Open Visual Studio .Net Select the menu : File > New > Project Choose from the project types : Visual C# Projects From the Templates, choose the application type 'Windows Application' Enter the project name in the space for 'Name'. Make sure the 'Location' is pointing to your folder. You may press the Browse button to select your personal folder, so that all your projects will be saved in your folder.

Press 'OK' to create the projet. By default the project will be created with a sample form, named 'Form1'. You can drag and drop controls into this form, from the 'Toolbox' on the left hand side of the VS.Net.

Displaying Simple MessageBox Simple MessageBox

Download Sample .Net project for MessageBox program

MessageBox.zip

This chapter and the attached sample application will give you a brief idea about the following: Reading the text value from a textbox Displaying a message box About the sample application This application has 1 textbox and a button. If you type anything in the textbox and press the button, it will display the same text you typed in a MessageBox. Download and unzip the sample application from this page. After you unzip, you will get several files. Some of the important files are : 1. Chapter1.csproj - This is the C# project file. Double click this file to open the project. 2. Form1.cs - This is the file for the Form1 in teh sample application. After you open the project, see the 'Solution Explorer' bar on the right side of the Visual Studio. You can click on that to expand it, which will display the list of all files in the project. (Or, you can go to the menu 'View > Solution Explorer' to open the solution explorer. Click on 'Form1.cs' in the solution explorer to open the Form. Now you can see the Form in 'design mode'. Right click on the 'Form1.cs' in the solution explorer and choose 'View Code' to see the source code behind this Form (Or, press F7 from the Form to see the code). Let us analyze the code: The code has lot of Visual Studio generated code. For timebeing ignore all those code and scroll down to the event handler code in the bottom of the file. System.Windows.Forms.MessageBox.Show( "You typed : " + txtMessage.Text ); DialogResult result = MessageBox.Show( "Did you like this application ?", "Caption", MessageBoxButtons.YesNo, MessageBoxIcon.Question ); if ( result == DialogResult.Yes ) MessageBox.Show("You selected YES"); else MessageBox.Show("You selected NO");

The first line will simply display a messagebox and show the text typed by the user. 'MessageBox' is a class inside the namespace 'System.Windows.Forms'. We have a statement 'using System.Windows.Forms' on top of the source code. This is like a source code. This will help us avoid typing 'System.Windows.Forms.' everytime when we want to use a class inside this namespace. The next few lines of code do a bit more. Here we are displaying a message box, with some additional attributes. The second optional parameter of the 'Show' method is the 'caption' for the messagebox. The third parameter tells that the messagebox will have two buttons - YES and NO. You have several other options like MessageBoxButtons.OK, MessageBoxButtons.OKCancel etc. And, the last parameter says 'display a question Icon in the messagebox'. There are many other types of icons you can display. And another important part is, the MessageBox returns a value when the user press a button to close the messagebox. Our MessageBox asks a question 'Did you like this application ?" and gives two options to the user YES or NO. The return value is of type 'DialogResult' and is assigned to the variable 'result'. We are checking the value of the result and depending on whether user pressed the YES button or NO button, appropriate message will be displayed. ------------------------------------------------------------------------------------------------------------------------------Basic File Operation Download Sample .Net Project for FileOperations

FileOperations.zip

This chapter will teach you the basic file operations. In the attached sample application, you can type some text and save into a text file. Also, you can select a text file and display the content in a textbox. In addition to the basic file operations, you can learn some good programming practices and error handling/validation techniques. This chapter and the attached sample application demonstrates the usage of following .net classes and methods: System.IO.Path.GetExtension() - Method to check the extension of a file. System.IO.File.Exists() - Check if a file alread exists. System.Windows.Forms.OpenFileDialog - "File Open Dialog" to choose a file from the disk. DialogResult.OK - Result from a File Open Dialog. MessageBox.Show() - Displaying a message to the user. string.Trim() - Remove white space characters from beginning and end of string. throw new Exception() - Create and throw a new exception. System.IO.StreamWriter - Stream writer to write into files. System.IO.StreamReader - Read from file. Application.Exit() - Closing an application

Retrieving html content from any URL Download Sample .NET Project for this chapter

HtmlRetrieve.zip

This chapter will teach you how to retrieve content of any website using .NET classes. This chapter and the attached sample application demonstrates the usage of following .NET classes and methods: System.Net.WebRequest() - Class to perform the web related operations. System.Net.WebRequest.Create(url) - Create a web request. System.Net.WebRequest.GetResponse() - Get the html content of the URL. System.IO.StreamReader - Read from file

Using Application Configuration File to store application specific information Download Sample .NET Project for this chapter.

AppConfig.zip

.NET gives an easy way to store configuration information in a Application Configuration File. In the simple implementation, you can store information as Key-Value pairs. For example, consider a case where you have to use a DataSource in your application. If you hardcore the DataSource information in your code, you will have a bad time when you have to change this datasource. You have to change your source code and re-compile it. This won't work everytime you give your product to different customers or when you run your application in different machines! In earlier days, programmers used to store this information in special files called ".ini" files or in system registry. The application can read the information from the .ini file or registry and no need to re-compile the code when the values are changed in .ini file or registry. But this is a pain most of the time. It is not fun opening the registry, locate your entries and make appropriate changes. It is quite possible that you may mess up with some important entries in the registry and make your system not running any more. In fact, in secured systems, administrator may deny access to the registry and users will not have the choice to edit the registry at all. .NET gives you a simple and easy solution for thsi proble - the Application Configuration File. Each application can have a configuration file, which is actually an XML file. You can use any text editor (including notepad) to open the configuration file and change the values. The application will load the values from this configuration file and you do not have to change your source code everytime you change your DataSource or any other information stored in configuration file. app.config for Windows applications Windows applications in VS.NET uses the name 'app.config' by default for the configuration file. This will not be automatically created when you create a Windows application. If you need a configuration file for your application, open your project in VS.NET, go to the 'Solution Explorer' and right click on the project name. Choose Add > Add new item from the menu and select 'Application Configuration file' from the list of choices. This will create an app.config file for you in the application root. By default, the app.config file will have the following content: <?xml version="1.0" encoding="utf-8" ?>

<configuration> </configuration> To store values in configuration file, you can create xml elements in the format <add key="MyKey" value="MyValue" /> See the sample config entries below: <?xml version="1.0" encoding= "utf-8" ?> <configuration> <appSettings> <add key="DatabasePath" value="c:\\projects\data\spider.mdb" /> <add key="SupportEmail" value="webmaster-2@dotnetspider.com" /> </appSettings> </configuration> And to read from this config file, just use the following code in your application: string dbPath = System.Configuration.ConfigurationSettings.AppSettings["DatabasePath"]; string email = System.Configuration.ConfigurationSettings.AppSettings["SupportEmail"]; ConfigurationSettings is the class used to access the contents of the configuration file. Since this class is part of the namespace System.Configuration, we have to use the fully qualified name System.Configuration.ConfigurationSettings. As a shortcut, you can use the using directive on top of the file like below: using System.Configuration; If you have the above directive on top of the file, then you can directly use the class ConfigurationSettings. string dbPath = ConfigurationSettings.AppSettings["DatabasePath"]; string email = ConfigurationSettings.AppSettings["SupportEmail"]; In VB.NET, you have to use "( ... )" instead of the "[ ... ]", as shown below: Dim dbPath as String = ConfigurationSettings.AppSettings("DatabasePath") Dim email as String = ConfigurationSettings.AppSettings("SupportEmail") Note: When you compile your application, VS.NET will automatically create a file called <your application name>.exe.config in your bin\debug folder. The contents of the app.config will be automatically copied to this new config file when you compile the application. When you deliver the application to the end user, you have to deliver the exe and this new config file called <your application name>.exe.config and NOT the app.config. Users can modify the data in <your application name>.exe.config file and application will read the data from the config file, when restarted. web.config for web applications The web applications use the same concept, but they use a config file with the name 'web.config'. There are couple of things to note in this case.

web.config is created automatically by VS.NET when you create any web project. When you compile the web application, web.config is NOT renamed or copied to the BIN folder. web.config has several default entries in it to support web/IIS configuration & security. You can add the <appSettings> section in the web.config and add your key/value pairs in that section. You can have separate web.config files for each directory in your web application, in addition to the one in the root. For each web page, by default system will look for a web.config in the same folder as the page and if not found, then looks in the parent folder. Debugging in VS.NET If you make a syntax error, then the compiler will tell you and you can easily solve the issue. But what if there is a logical error? You may never know what went wrong, just by looking into the code. During runtime, the application may give wrong results, which may not be noticed immediately by anyone. When someone report that your "calculator program" gives the result 10 when adding 5 and 4, what will you do? A logical error in a small calculator program may be an easy to fix issue, but what if it is a very complex accounting software? The Debugger becomes a very handy tool in such situations. A Debugger is a software process that help you monitor the execution of your code. Microsoft gives us a very powerful debugger, integrated with the VS.NET. When you execute your code in debug mode, you can watch how it executes each line of code. You can run (debug) the application step by step, line by line and see the value of each variable at any point of time. You can visually count how many times a while loop executes and see whether it executes the if block or else block. So, in short, debugger help you watch how your code is executed. You can see how your calculator program calculates 5 + 4 = 10 and easily figure out the logical error. Debugging your project Running your project in Debug mode doesn't need lot of work. Just choose the menu : Debug > Start or press F5. Now your application will run in debug mode. To run your application in non-debug mode, choose the menu : Debug > Start without Debugging or press Ctrl F5. You may not feel any difference whether you run in debug mode or non-debug mode. In both the cases, your application runs as usual! To find the difference, you can use breakpoints. BreakPoints BreakPoints are used to stop the execution at certain lines of code in the application and monitor the values of various variables etc at that point of time. To put breakpoints, click on any line of code and press F9 or click on the leftbar of any line of code. When a breakpoint is enabled, the line will be highlighted with BROWN color and a BROWN circle will appear on the left bar (See image below). To remove a breakpoint, press F9 again. Open your project and mark breakpoints in different lines of code. Now start the debugger by pressing F5. Note that every time the execution passes through the lines marked as 'breakpoint', execution stops there. You can press F5 to continue the execution again. Or, press F10 to continue the execution line by line! When the execution stops on a breakpoint, or when you continue execution line by line by pressing F10, you can point your mouse over any variable and it will show you the value of that variable at that point of time. You can see how the values are changed at each line of code and this helps you easily figure out the logical errors. This process is called 'Debugging'. Next time, when you hear someone complaining about his 'debugging nightmares', you know what it is! Change path of execution When the execution reaches a breakpoint, you can see a little YELLOW Arrow on the leftbar of the current line of code and the line will be highlighted with YELLOW color (See image below). When you press the F10, the execution will proceed to the next line of code. You can change this execution path by clicking on the yellow arrow on the leftbar and dragging it into

any other line of code. For example, if you are currently inside an if block, you can drag the execution to the else block (or, to some other line of code), thus changing the application behaviour the way you want! Don't you agree that the Debugger is a very powerful tool? Quick Watch While debugging, you can view the value of any variable instantly by pointing the mouse over the variable (See image below. You can see a very small light yellow window showing name = "Little John". This is displayed when the mouse is pointed over the variable name). But this will work only for simple types like int, string etc. In case of types like DataTable, DataSet, ArrayList etc, you can right click on the object name and choose Quick Watch. A small window will open and will show you the complete object. You can expand the properties of the object and view the values of each proeprty. In case of a DataSet, you can Quick Watch the dataset and expand each table inside the dataset, each row in each table, each column in each row etc. Thus the Quick Watch will help you view the values of the 'complete object'. Watch Window When you debug the application and step through each line, it is not really necessary to point the mouse on each variable to view the value. Just add the variable to the 'Watch Window' and the values are always visible in the little 'Watch Window' in the bottom of your VS.NET (see image below. The variable name is added to the watch window). To add any variable to Watch Window, righ click on the variable and choose 'Add Watch'. You can choose the same option from the 'Quick Watch' window also. The 'Watch Window' may be minimized by default. You can point your mouse on the 'Watch' icon in the bottom of the VS.NET to expand this window. Use the 'push button' in the watch window to keep it always expanded. If 'Watch Window' is not visible in the bottom, select the menu option from VS.NET main menu : Debug > Windows > Watch > Watch 1 System.Diagnostics.Debug.WriteLine You may use System.Diagnostics.Debug.WriteLine to print any values into the output window while debugging. Ex: System.Diagnostics.Debug.WriteLine( "*** My name is : " + name ); System.Diagnostics.Debug.WriteLine( "+++ See the Output window now." ); System.Diagnostics.Debug.WriteLine( "=== End." ); See the image below to see how it appears in the output window.

Advanced features The debugger comes with several other advanced features like conditional breakpoints, CallStack etc. You may find more information from MSDN or other web sites. To keep it simple and helpful for beginners, we have mentioned only the commonly used features of VS.NET debugger.

Database Operations

Accessing database using ADO.NET in C# or VB.NET This tutorial will teach you Database concepts and ADO.NET in a very simple and easy-to-understand manner with many code snippets and samples. This is primarily meant for beginners and if you are looking for any advanced ADO.NET topics, this may not be the right page for you. Database Concepts Database is the media to store data. If you have an application that has to store and retrieve data, your application must be using a database. A 'File' is the simplest form of saving the data in the disk, but is not the most 'efficient way' of managing application data. A database is basically a collection of one or more files, but in a custom format, and data is organised in a specific format such a way that it can be retrieved and stored very efficiently. Some examples for databases are : MS Access SQL Server Oracle MS Access is a very light weight database provided by Microsoft for applications with less number of users and relatively small quantity of data. MS Access saves data into database files with the extension .mdb. Usually, MS Access comes along with MS Office package. If you already have the .mdb database file, you can freely use it with your application and you do not need MS Access software. The MS Access software is required only if you want to directly open the database and manipulate the data or change the database schema.

SQL Server (Microsoft product) and Oracle (Oracle Corp.) are more complex, advanced, relational databases and they are much more expensive. It can support large number of users and very high quantity of data. If you are developing a software, which might be accessed simulatenously by 100s of users or if you expect your data may grow 100s of MBs, you might consider one of these. (We are learning Microsoft .NET.. so you might want to consider the SQL Server than Oracle, for which Microsoft provides special data access components!!) In this tutorial, we will be using only MS Access for simplicity. Most of the samples provided in this site uses MS Access database for simplicity and easy download. ADO.NET ADO.NET is the data access model that comes with the .NET Framework. ADO.NET provides the classes required to communicate with any database source (including Oracle, Sybase, Microsoft Access, Xml, and even text files). DataAccess Providers in .NET ADO.NET comes with few providers providers, including: OleDb SqlClient There are other providers available, but we are not including them here as this tutorial is meant for beginners! When you want them, search for ADO.NET providers in Google or MSDN Microsoft made the SQL Server. So they gave a separate provider, specifically made for SQL Server. We can use the OleDb provider for all other database sources including MS Access, Oracle, Sybase etc. There is a separate provider available for Oracle. A DATA PROVIDER is a set of classes that can be used to access, retrieve and manipulate data from the databases. Both OleDb and SqlClient has it's own set of classes, but they have the same concepts. We would like to classify the classes into two broad categories (this is not a microsoft classification, anyway!) Classes for communicate with database Classes for holding/manipulating data The job of first category of classes is to communicate with database and send or retrieve data from the database. The second category of the classes will be used as a carrier of data. Classes for communicating with database The Connection, Command, DataReader, and DataAdapter objects are the core elements of the ADO.NET provider model. Object Description SqlClient Objects SqlCommand SqlDataReader OleDb Objects OleDbConnection OleDbCommand OleDbDataReader OleDbDataAdapter

Connection Establishes a connection to a specific data source. SqlConnection Command Executes a command against a data source. DataReader Reads a forward-only, read-only stream of data from a data source.

DataAdapter Populates a DataSet and resolves updates with the SqlDataAdapter data source.

Each provider may have classes equivalent to above objects. The name of the classes vary slightly to represent the provider type appropriately.

Depending on the type of database you work on, you will have to choose either OleDb or SqlClient (or, some other provider) objects. Since all our samples use MS Access database, we will be using OleDb objects in all the samples. If you like to use SqlServer, you just need to replace the OleDb objects with the equivalent SqlClient objects. Classes for holding data The following are the main classes used to hold data in Ado.NET: DataSet DataTable DataRow A DataSet is an in-memory representation of the database. DataSet contains DataTables (and more...) DataTable represents a database table DataTable contains DataRows (and more...) A DataRow represents a record in a database table. DataRow is a collection of all fields in a record.

We can use the DataAdapter or DataReader to populate data in DataSet. Once we populate data from database, we can loop through all Tables in the DataSet and through each record in each Table. On the first look, this may look bit confusing, but once you understand the concept and get familiar with the Ado.NET classes, you will appreciate the power and flexibility of Ado.NET. Soon, we will publish several Ado.Net samples here. Please check back soon. Install our SpiderAlerts utility to get instant alert in your desktop when we update new chapters and articles! -----------------------------------------------------------------------------------------------------------------------------------------Basic Database operations using ADO.NET - CRUD (Create, Read, Update, Delete) Click here to download sample project and database

CRUDSample.zip

This chapter demonstrates the basic database operations using the ADO.NET classes. The sample code in this chapter uses the OleDb Provider. Here is some sample code to execute a simple query. string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb"; OleDbConnection myConnection = new OleDbConnection( connectionString ); myConnection.Open(); string query = "insert into EMPLOYEE_TABLE (EmployeeID, Name, Address) VALUES (101, 'John', '3960 CliffValley Way')"; OleDbCommand myCommand = new OleDbCommand(); myCommand.CommandText = query; myCommand.Connection = myConnection; myCommand.ExecuteNonQuery();

myConnection.Close(); Let us analyze the code. First we have declared a connection string. The connection string points to an MS Access database. Before you execute this code, make sure you have the database in the path specified. Or, change the path accordingly. In the next step, we are creating a OleDbConnection object and passing the connection string to this object. The line 'myConnection.Open();' will open a connection to the MS Access database specified in the connection string. If the database doesn't exists or if it is not able to open a connection for some other reason, the '.Open' call will fail. Next step is, creating a OleDbCommand object. This command object is used to execute sql statements and uses the connection opened by the OleDbConnection object. Note that before executing a command, we have to establish a valid connection to the database. And finally, after we have executed with the command, we will close the connection. The above sample code executes a sql statement and returns no data from database. We are calling the method 'ExecuteNonQuery()' on the command object. If we have a 'select ...' statement which returns data from database, we cannot use the 'ExecuteNonQuery()' method. The following sample demonstrates using OleDbDataAdapter Object and DataSet to retrieve data from databbase. string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb"; OleDbConnection myConnection = new OleDbConnection( connectionString ); string query = "select * from EMPLOYEE_TABLE"; OleDbDataAdapter myAdapter = new OleDbDataAdapter( query, myConnection ); DataSet employeeData = new DataSet(); myAdapter.Fill ( employeeData ); Here we are creating a OleDbConnection object and we are just passing the object to the OleDbDataAdapter object. Also, we pass the 'select ...' query to the OleDbDataAdapter. Next, we call the '.Fill()' method of the OleDbDataAdapter. This step will populate the dataset ( called 'employeeData' ) with the data retrieved for the sql statement 'select * from EMPLOYEE'. As you already know, a DataSet can contain a collection of tables. But in our case, our sql statement will retrieve data from only one table. So, our DataSet will have only one table. We can iterate through the table in the dataset and retrieve all the records. See the following code demonstrating this: string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb"; OleDbConnection myConnection = new OleDbConnection( connectionString ); string query = "select * from EMPLOYEE_TABLE"; OleDbDataAdapter myAdapter = new OleDbDataAdapter( query, myConnection ); DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); // Repeat for each table in the DataSet collection. foreach ( DataTable table in employeeData.Tables ) { // Repeat for each row in the table. foreach ( DataRow row in table.Rows )

{ MessageBox.Show( "Employee Number : " + row["EmployeeNumber"].ToString() ); MessageBox.Show( "Name : " + row["Name"].ToString() ); MessageBox.Show( "Address : " + row["Address"].ToString() ); } } The above code retrieves all the records from the employee table and displays all the fields. You can download a sample project demonstrating the basic database operations. -----------------------------------------------------------------------------------------------------------------------------------------DataSet, DataTable, DataRow Manipulating Data using DataSet and DataTable DataSet and DataTable are the key components in ADO.NET programming. In simple words, DataSet represents an in memory representation of the database. We can load an entire database into a DataSet and manipulate the data in memory. If you are more familiar with DataSet, you can Add, Edit and Update data in the dataset and then just call a single method 'AcceptChanges()' which will save all the changes back to the database. A DataSet contains one or more DataTables A DataTable contains DataRows. What is DataSet ? A DataSet is an in memory representation of data loaded from any data source. Even though the most common data source is database, we can use DataSet to load data from other data sources including XML files etc. In this article, we will talk about the role of DataSet in manipulating data from database. In .NET, a DataSet is a class provided by the .NET Framework. The DataSet class exposes several proeprties and methods that can be used to retrieve, manipulate and save data from various data sources. Just like any other classes in object oriented programming, we have to create an instance of DataSet class to work with data. Typically, we may create a new instance of a DataSet and use other classes provided by .NET Framework to populate the DataSet. See the following example: string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb"; OleDbConnection myConnection = new OleDbConnection( connectionString ); string query = "select * from EMPLOYEE_TABLE"; OleDbDataAdapter myAdapter = new OleDbDataAdapter( query, myConnection ); DataSet employeeData = new DataSet(); myAdapter.Fill ( employeeData );

Here we are creating a OleDbConnection object and we are just passing the object to the OleDbDataAdapter object. Also, we pass the 'select ...' query to the OleDbDataAdapter. Next, we call the '.Fill()' method of the OleDbDataAdapter. This step will populate the dataset ( called

'employeeData' ) with the data retrieved for the sql statement 'select * from EMPLOYEE'. As you already know, a DataSet can contain a collection of tables. But in the above case, our sql statement will retrieve data from only one table. So, our DataSet will have only one table. Commonly used properties and methods of DataSet Property : Tables The Tables propertly allows us to retrieve the tables contained in the DataSet. This property returns a DataTableCollection object. The following sample code demonstrates iterating through the collection of tables in a data set and print the name of all the tables. DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); // Repeat for each table in the DataSet collection. foreach ( DataTable table in employeeData.Tables ) { MessageBox.Show ( table.TableName ); } Or, you can use the indexer to access any specific table in the collection. DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); // Repeat for each table in the DataSet collection. for ( int i = 0; i < employeeData.Tables.Count; i++ ) { DataTable table = employeeData.Tables[i]; MessageBox.Show ( table.TableName ); } Method : GetXml() The GetXml() method returns the XML representation of the data from the DataSet. DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); string xmlData = employeeData.GetXml(); Method : WriteXml(...) The WriteXml() method allows to save XML representation of the data from the DataSet to an XML file. There are many overloaded method available, which takes various parameters. The example shown below takes a file name as parameter and saves the data in DataSet into xml format to the file name specified as parameter. We can optionally save only the data or both data and schema. DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); employeeData.WriteXml( "c:\\MyData.xml" ); Method : ReadXml(...) The ReadXml() method allows to load the DataSet from an XML representation of the data. There are

many overloaded method available, which takes various parameters. The example shown below takes a file name as parameter and loads the data from XML file into the DataSet. This method can be used to load either the data only or both data and schema from the XML. DataSet employeeData = new DataSet(); employeeData.ReadXml( "c:\\MyData.xml" ); There is another method called 'ReadXmlSchema()', which can be used to load only the schema from a file. The methods WriteXml() and ReadXml() are useful to save the data from a database into some temporary files, transport to other places or keep it as a local file and load later. Many applications, including the SpiderAlerts tool available for download from this site, uses DataSet to manipulate data and saves/retrieves them from local disk using the WriteXml() and ReadXml() methods. The SpiderAlerts tool communicates with webservices in our site and retrieves the alerts in the form of a DataSet. Once the Alerts are retrieved, it is saved into local computer using the WriteXml method. (This implementation may be changed soon in the future versions of this tool. We are considering saving(serializing) the DataSet into Isolated Storage (IsolatedStorage is a new feature part of the .NET Framework - it is a kind of hidden file system). You can read more about Isolated Storage here: http://www.dotnetspider.com/Technology/KBPages/18.aspx http://www.dotnetspider.com/Technology/KBPages/344.aspx The source code for the SpiderAlerts tool will be available in this site's projects section soon. -----------------------------------------------------------------------------------------------------------------------------------------DataTable class in ADO.NET A DataTable is a class in .NET Framework and in simple words a DataTable object represents a table from a database. DataSet and DataTable are the key components in ADO.NET programming. While DataSet can be used to represent a database as a whole, a DataTable object can be used to represent a table in the Database/DataSet. A DataSet can contain several DataTables. In typical database oriented applications, DataSet and DataTable are used a lot to manipulate data. DataAdapter or other classes can be used to populate a DataSet. Once a DataSet is populated, we can access the DataTables contained within the DataSet. Just like any database table contains multiple rows (records), a DataTable can contain multiple DataRows. Each row contains multiple fields representing each column in the table. The typical process to retrieve records from a database in ADO.NET includes the following steps: Open a connection to database Use a data adapter to fill a DataSet. Access the DataTable contained in the DataSet Access the DataRows contained in the DataTable.

The following sample code explains these steps. This sample code retrieves data from an MS Access database. string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb"; OleDbConnection myConnection = new OleDbConnection( connectionString );

string query = "select * from EMPLOYEE_TABLE"; OleDbDataAdapter myAdapter = new OleDbDataAdapter( query, myConnection ); DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); // Repeat for each table in the DataSet collection. foreach ( DataTable table in employeeData.Tables ) { // Repeat for each row in the table. foreach ( DataRow row in table.Rows ) { MessageBox.Show( "Employee Number : " + row["EmployeeNumber"].ToString() ); MessageBox.Show( "Name : " + row["Name"].ToString() ); MessageBox.Show( "Address : " + row["Address"].ToString() ); } } How to create a DataTable In most of the cases, we just access the DataTable in a DataSet. We do not need to create a new instance of the DataTable. When a DataSet is populated from database, the DataTable is created with proper schema and data. If we explicitely create DataTable, we have to create the proper schema. It is bit confusing if you are not very familiar with the database structure and schema.

Exception Handling Exception handling in .NET Framework If you write a program, it is for sure that it will have errors and issues. You cannot avoid them. But what you can do is write the code such a way that it is easy to find the errors and issues so that you can solve them easily. You need the real skill to write 'maintainable code'. What is maintainable code ? If an existing application is given to a new employee in the company and ask him to fix a problem in that, most probably he will come back with the answer : "oh, it is stupid code.. I can't figure out what they have written. Instead of trouble shooting the issues in this code, I can re write the entire application with less time." This is a common scenario in the programming world. The above answer shows the code is not a maintainable code. Over a period of time, there will be lot of changes required in existing applications to adapt to the new requirements. Only if you write 'maintainable code', you can enhance your application when new requirements come up and solve issues. There is no specific set of rules to make an application 'maintainable'. There are lot of factors involved in it including following coding standards, writing lot of comments within code, writing self explanatory code, separating application into multiple well defined layers, having good exception handling etc. What is an 'Exception' ? 'Exception' is an error situation that a program may encounter during runtime. For example, your program may be trying to write into a file, but your hard disk may be full. Or, the program may be trying

to update a record in database, but that record may be already deleted. Such errors may happen any time and unless you handle such situation properly, your application may have un predictable behaviour. What is the difference between 'Exception' and 'Error' ? Error is an expected situation in an application. For example, you want to create a file in the folder "C:\Projects\Test\". If you attempt to create a file when this folder doesn't exists, it will make the operating system throw an exception. But you should not leave it to the operating system to throw the exception. This has to be handled through code. You must first check for the existence of the folder before you attempt to write the file. If the folder doesn't exists, you must first create the folder. This is how a stable application should be written. Exception is a runtime error that the program may encounter during the execution of the program. For example, hard disk may be full when you attempt to write into a file, network connection may be lost while your application is communicating with another computer etc. There is no clear definition, but typically, Exceptions are unpredictable errors during runtime. What is 'Exception Handling'? When you ride a bike, you may wear a helmet. When you go for boating, you might use a life jacket. A car driver might use seat belts while driving at high speed in a high way. What is the purpose ? To handle exceptions (accidents), right ? We do not know when it might happen, so we are prepared to 'handle' such situations any time. An exception can occur anytime during the execution of an application. Your application must be prepared to face such situations. An application will crash if an exception occurs and it is not handled. "An exception handler is a piece of code which will be called when an exception occurs." .NET Framework provides several classes to work with exceptions. The keywords try, catch are used to handle exceptions in .NET. You have to put the code (that can cause an exception) in a try block. If an exception occurs at any line of code inside a try block, the control of execution will be transfered to the code inside the catch block. Syntax : try { // Code which can cause an exception. } catch(Exception ex) { // Code to handle exception } Just like a bike rider wrap his head in a helmet to protect from accident, the above syntax will protect the code within the try block from accidents (exceptions). If any statement within the try block raises an exception, the control of execution will be transfered to the first line within the catch block. You can write the error handling code in the catch block, like recording the error message into a log file, sending an email to the administrator about the problem occurred, showing an appropriate error message to the user etc. See the following code : try { Statement 1 Statement 2

Statement 3 } catch(Exception ex) { Statement 4 Statement 5 } Statement 6 In normal flow of program, the statements 1, 2, 3, 6 will be executed. Statements 4 and 5 will be executed only if an exception occurs. Assume there is an exception at statement 2. In this scenario, statements 1, 2, 4, 5 and 6 will be executed. Statement 3 will not be executed at all, because an exception occurred at statement 2 and program flow was transfered to the catch block. 'finally' block You can optionally use a 'finally' block along with the try-catch. The 'finally' block is guaranteed to be executed even if there is an exception. Sample Code : try { Statement 1 Statement 2 Statement 3 } catch(Exception ex) { Statement 4 Statement 5 } finally { Statement 6 Statement 7 } Statement 8 In normal flow of program, the statements 1, 2, 3, 6, 7 and 8 will be executed. Statements 4 and 5 will be executed only if an exception occurs. Assume there is an exception at statement 2. In this scenario, statements 1, 2, 4, 5, 6, 7 and 8 will be executed. Note that the statements 6 and 7 are executed in both the cases. The bottom line is, the code within the 'finally' block is executed whether there is an exception or not. You can use the finally block to do any code cleanup. For example, you are doing some database operations inside a try block. try { Statement 1 - Open database Statement 2 - Execute Query Statement 3 - Close Database }

catch(Exception ex) { Statement 4 - Show messagebox to user } In the above code sample, what will happen if an exception occurs when the statement 2 is executed ? The catch block will be executed and a message box will be shown to the user. But the Statement 3 is never executed in that case, which means the database will not be closed. Here is where the finally block will be helpful. try { Statement 1 - Open database Statement 2 - Execute Query } catch(Exception ex) { Statement 3 - Show messagebox to user } finally { Statement 4 - Close Database } See the improved code. We have moved the code to close the database to the 'finally' block. The statement to close the database will be executed whether there is an exception or not.

Why should we catch exceptions ? Why should you use a helmet when you ride a bike ? To protect your head from crashing when there is an accident, right ? Just like that, exception handling will protect your application from crashing when there is an exceptions. If an exception is not 'handled' in code, the application will crash and user will see an ugly message. Instead, you can catch the exception, log the errors and show a friendly message to the user. Exception classes in .NET Framework .NET Framework provides several classes to work with exceptions. When there is an exception, the .NET framework creates an object of type 'Exception' and 'throws' it. This Exception object contains all information about the 'error'. If you enclose your code within the try-catch block, you will receive the exception object in the 'catch' block when the exception occurs. You can use this object to retrieve the information regarding the error and take appropriate action. try { // Code which can cause an exception. } catch(Exception ex) { // Code to handle exception MessageBox.Show ( ex.Message ); } Within the catch block, you can use the Exception object to get more information about the error. The exception object exposes a property called 'Message', which gives a description about the error. This may not be a very friendly message for the end user. But you can use it to log the error and show another friendly message to the user.

The System.Exception class In .NET, all exceptions are derived from the Exception class. The Exception class is defined inside the System namespace. Other derived exception classes are spread across many other namespaces. Since all other exceptions are derived from the System.Exception class, if you catch System.Exception, that would cover all exceptions derived from System.Exception also. So, the statement catch (Exception) would catch all exceptions of type System.Exception and all derived exceptions. In .NET, all exceptions are derived from System.Exception. So, catch (Exception) will catch all posibble exceptions in your .NET application. Specify what exception type you want to catch See the catch block in the above sample code. catch ( Exception ex ) - specifies that we want to catch all exceptions of Type Exception. So, if there is an exception of Type Exception, it will be caught by the catch block. If you specify an exception Type in the catch statement, it will catch all exceptions of the specified type and all types derived from it. See the following sample : try { // Code which can cause an exception. } catch(System.Web.HttpException ex) { // Code to handle exception MessageBox.Show ( ex.Message ); } The above example will only catch the exception of type System.Web.HttpException and any other exception derived from it. So, if there is any exception of type System.ArithmeticException, it will not be handled and it may lead to program termination. Handling specific Exception types In my previous article, I mentioned few examples from real life - "When you ride a bike, you may wear a helmet. When you go for boating, you might use a life jacket. A car driver might use seat belts while driving at high speed in a high way. What is the purpose ? To handle exceptions (accidents), right ? We do not know when it might happen, so we are prepared to 'handle' such situations any time. " Yes, a helmet helps a bike rider when he meet with an accident. A life jacket may be helpful in water and a seat belt would help a car driver. But what if some one ride a bike with a helpmet, life jacket and a seat belt ? That may not look good, right ? Similarly, in Exception handling, you do not need to catch all exceptions. You need to catch only the 'expected' exceptions. Which means, if you are doing an arithmetic calculation, you must handle ArithmeticException and DivideByZeroException. When you are accessing the web from your code, you must handle HttpException. The bottom line is, depending on the nature of the code, you must handle the appropriate, specific exceptions, instead of catching the father of all exceptions (System.Exception). Multiple catch blocks You can have any number of catch blocks for each try block. For example, if you are doing some operation which involve web access and also some arithmetic operations, you can handle both System.Web.HttpException and System.ArithmeticException. See the sample below: try

{ // Code which can cause a web exception or arithmetic exception. } catch(System.Web.HttpException ex) { MessageBox.Show ( "A web exception occurred." ); } catch(System.ArithmeticException ex) { MessageBox.Show ( "An arithmetic exception occurred." ); } Program Flow When an exception occurs within a try block, the program control will jump to the first catch block and compare if the exception type is same the as the type specified in the catch block. If the type matches, it will execute the catch block. If the types do not match, it will jump to the next catch block and compare. Like this, it will compare against all catch blocks until a match is found. If there is no catch block found which matches the exception type, it will become an unhandled exception and will lead to program termination Catch derived exceptions first and base exception last A base exception type will match the derived exceptions also. If there is a catch block with the type 'Exception', it will catch all types of exceptions. So, you have multiple catch blocks, you must specify the derived exception types first and the base types last. See the following code: try { // Code which can cause a web exception or arithmetic exception. } catch (System.Exception ex) { MessageBox.Show ( "An exception occurred." ); } catch (System.Web.HttpException ex) { MessageBox.Show ( "A web exception occurred." ); } In the above code, assume there is a web exception occurred. The exception type will be compared against the first catch block. Since the WebException is derived from System.Exception or oneof it's derived classes, the types will match and the first catch block will be executed. So, you might be expecting that the catch (System.Web.HttpException) block will be executed, but it would never get called because of the catch(System.Exception ex) before that. You must change the above code as shown below : try { // Code which can cause a web exception or arithmetic exception. } catch (System.Web.HttpException ex) { MessageBox.Show ( "A web exception occurred." ); } catch(System.Exception ex) { MessageBox.Show ( "An exception occurred." );

} Now, if there is a web exception, it will go to the catch (System.Web.HttpException ex) block. All other exceptions will go to catch (System.Exception ex). Some commonly used .NET Exception classes System.ArithmeticException - This is the base class for exceptions that occur during arithmetic operations, such as System.DivideByZeroException and System.OverflowException. System.ArrayTypeMismatchException - ArrayTypeMismatchException is thrown when a an incompatible object is attpemted to store into an Array. System.DivideByZeroException - This exception is thrown when an attempt to divide a number by zero. System.IndexOutOfRangeException - IndexOutOfRangeException is thrown when attempted to access an array using an index that is less than zero or outside the bounds of the array. System.InvalidCastException - Thrown when an explicit type conversion from a base type or interface to a derived type fails at run time. System.NullReferenceException - This exception is thrown when an object is accessed but it is null. System.OutOfMemoryException - OutOfMemoryException is thrown if the 'new' operation (creating new object) fails due to in sufficient memory. System.OverflowException - OverflowException is thrown when an arithmetic operation overflows. System.StackOverflowException - StackOverflowException is thrown when the execution stack is exhausted by having too many pending method calls, most probably due to infinite loop. ArgumentException - The exception that is thrown when one of the arguments provided to a method is not valid. Traditional Visual Basic error handling and it's .... Difference between old Visual Basic "On Error" and new VB.NET exception handling If you are coming from Visual Badic background, you will find that the error handling mechanism is totally changed in VB.NET. Visual Basic provides an error handling mechanism, now called 'un structured error handling'. Typically, you will place a code statement "On Error Goto ErrorHandler" on top of your code block. This means, when an error occurs, jump to the path specified by 'Errorhandler'. See the following sample code : Sub MyMethod On Error GoTo ErrorHandler ' code that may raise an error Exit Sub ErrorHandler: ' Error handling code Resume End Sub In the above sample code, if an error occurs in the method, the program execution will jump to the ErrorHandler block. This saves your program from terminating abnormally and gives an opportunity to log the error details and show friendly message to the user.

Equivalent of On Error in VB.NET and C# Many programmers coming from Visual Basic to .NET asks this question : "what is the equivalent of On Error in .NET ?". The answer is, there is no direct equivalent. Just for backward compatibility, VB.NET supports the "On Error" statement. This is not available in C#. Even though "On Error" statement is supported in VB.NET, you are strongly encouraged to use the new structured exception handling mechanism provided by the .NET Framework. The above sample code can be re written in VB.NET as shown below : Private Sub MyMethod() Try ' code that can raise an error Catch ex As Exception ' code to handle the exception. End Try End Sub Read the other articles related 'Exception handling' to find more about the structured exception handling in .NET. Custom Exceptions How to write custom exception classes in C# The Microsoft .NET team has done a good job by providing us a rich set of Exception classes. Most of the time, these exception classes are sufficient enough to handle any common error situation. However, it may be required that our application would need some additional exception classes, that are not available in .NET Framework. The .NET Framework exception handling mechanism allows us to create our own custom exception classes and use it in our applications. Custom Exceptions All exceptions in .NET are derived from the root exception class - System.Exception. There are two other exception classes immediately derived from the System.Exception : System.SystemException System.ApplicationException All exceptions thrown by the .NET Framework is derived from the SystemException class. If we raise any exception from our application, it should be derived from the System.ApplicationException. This will differenciate our exceptions from the system generated exceptions. It is easy to create a custom exception class. Just create a new class and mark it as derived from System.ApplicationException public class UserNotExistsException : System.ApplicationException { } Now we have derived a custom exception class and we can use it in ourr application. See the sample code, showing how we can throw ourr custom exception. public void UpdateUser( User userObj ) { if ( some error condition ) { throw new UserNotExistsException();

} } The 'throw' statement allows us to raise an exception programmatically. Here we are creating a new object of type 'UserNotExistsException' and throwing it. Another class or method which calls our method should handle this exception. try { UpdateUser( userObj ); } catch ( UserNotExistsException ex ) { MessageBox.Show ( ex.Message ); } In this sample, we are calling the method UpdateUser(...), which might throw an exception of type UserNotExistsException. If this exception is raised, it will go to our catch block and we are showing a message to the user. Enhancing our custom exception In the custom exception we defined above, we haven't specified any constructor. But since we derive it from the ApplicationException, it will use the public contructors available in AppicationException. It is a good idea to provide atleast one constructor, which takes an error message as a parameter. public class UserNotExistsException : System.ApplicationException { public UserNotExistsException ( string message ) : base ( message ) { } } Now, when we throw this exception, we have to pass an error message to the constructor. The error handlers will be able to retrieve this message from the Exception object and show a better message to the user. public void UpdateUser( User userObj ) { if ( some error condition ) { throw new UserNotExistsException( "The user you are trying to update does not exists." ); } } See the exception handler code : try { UpdateUser( userObj ); } catch ( UserNotExistsException ex ) { MessageBox.Show ( ex.Message ); } Now the user will see the more friendly error message which we passed as part of the exception, while throwing it. You can customize the custom exception classes such a way that it passes any information you want including the date and time the exception occurred, the method name in which the exception was first raised, user name of the current user etc. You may also provide a Save() method for your custom

exception class so that when a caller catch our custom exception, he can call the Save() method, which will record the error information to the disk. XML Files Introduction to XML XML stands for eXtended Markup Language. XML has some similarities to HTML, which is also another Markup Language (HyperText Markup Language). An important difference between XML and HTML is, XML is used to define data, while HTML is basically used to display/format text. Main use of HTML is to make web pages. But XML is used in a wide variety of applications now and is becoming a standard for data exchange between different paltforms. Unlike HTML, XML has no pre-defined set of tags. You can define your own tags to structure and organize your data. Let us see some sample XML : <Company> <Employees> <Employee Id="101" Name="John" ></Employee> <Employee Id="102" Name="Lisa" ></Employee> <Employee Id="103" Name="Bill" ></Employee> </Employees> <Departments> <Department Name="Sales"></Department> <Department Name="Software"></Department> <Department Name="HR"></Department> </Departments> </Company> The above piece of XML is quite self explanatory. It is used to represent the data related to a company. One thing to note here is, the tags like <Company>, <Employees> etc are not predefined. Any XML document can have it's own set of tags. Only thing is, a valid XML document should follow some rules (like each tag should have a matching closing tag. There more such rules...) Need for XML XML is a platform neutral standard. Since it is represented in plain text, any platform can understand it. You can use XML to exchange data between Unix and Windows, Mainframes and windows applications and virtually any other platforms. It is a simple, easy to use *language* to exchange/store data. In real world, if you have to store data, you have several choices. One of the most common mechanism is databases. Databases are the best choice if you have lot of data to be stored/manipulated. But if you have to send data to another application or platform, databases will not be much helpful. Suppose you have your data stored in an SQL Server database. What if your manager ask you to give the list of Employees in the Sales department ? How will you give the data to him? You cannot give your SQL Server database to him. He may not have a SQL Server software or he may not have the technical expertise to view data from SQL Server. XML is very helpful in such scenarios. You just need to generate an XML from the SQL Server database with the required records and hand over the XML as a print out or email. XML is so simple so that any one can simply read it using any text editor. There are several XML viewers and editors available, which will help you read XML in the form of a tree view. Internet Explorer is a good XML viewer. Simply copy the above XML and save into a file called 'sample.xml'. Then open the xml file in internet explorer and see how it works! You can define your own XML tags based on your needs. You can have nested tags too, which help you organize the data any way you want it. See a slightly different version of the above XML: <Company> <Employees>

<Employee Id="101" Name="John" ></Employee> <Employee Id="102" Name="Lisa" ></Employee> <Employee Id="103" Name="Bill" ></Employee> </Employees> <Departments> <Department Name="Sales"> <Manager> <Name>Fred</Name> <Address>3000 Briarcliif Way</Address> <Email>Fred@spiderkerala.com</Email> <Phone> <ResidencePhone>616 304 1093</ResidencePhone> <OfficePhone>616 304 1093</OfficePhone> </Phone> </Manager> </Department> <Department Name="Software"> <Manager> <Name>Joe</Name> <Address>3960 Whispering Way</Address> <Email>Joe@spiderkerala.com</Email> <Phone> <ResidencePhone>616 304 1093</ResidencePhone> <OfficePhone>616 304 1093</OfficePhone> </Phone> </Manager> </Department> </Departments> </Company> The XML data altogether is called an 'XML Document'. .Net gives several classes to read and manipulate XML Documents. We will explore some of them in upcoming chapters. You might have seen our Tutorial Index, which lists all chapters. You can click on any chapter title and navigate to the corresponding page. This index is populated from an XML file. Click here to view the XML file, from which we load our tutorial chapters. The reason we load it from an XML file is, our chapters are continuously changing and we add new chapters frequently. All our chapters have a link to Next Chapter. If we hard-code these links in all chapters, we have to make changes in several places when we change the order of some chapters or when we add new chapters. There is all possibility that we might make some mistakes and some of the chapters may lead to 'wrong next chapter'. In our current implementation, we programmatically read the XML file and display the Tutorial Index. Also, each page has a piece of code which read the current page URL and find the Next Page Url from the XML file based on the current page URL. This mechanism helps us add new chapters without making any changes to existing pages. All we have to do is, just insert one line of entry in the XML file and the changes will be automatically reflected in all other relevant pages. Even if we want to re-order some of the chapters, we just need to re-arrange the entries in the XML file. We use the following code to load our Chapter Index from the XML file: public string GetChapters( string filePath ) { // Create an xml document. XmlDocument doc = new XmlDocument(); // Load the XML from the file. doc.Load(filePath);

// Retrieve all categories from the xml. XmlNodeList categories = doc.SelectNodes("DotNetSpider/Tutorials/Category"); string chapterString = ""; int chapter = 0; // Iterate through all the categories foreach ( XmlNode categoryNode in categories ) { // Add category name to the string. chapterString += "<BR><BR><font size=4>" + categoryNode.Attributes["Name"].Value + "</font><BR>"; // Get all chapters in the current category. XmlNodeList chapters = categoryNode.SelectNodes("Chapter"); // Loop through all chapters in the current category and add to the string. foreach ( XmlNode chapterNode in chapters ) { ++chapter; chapterString += " <LI>Chapter " + chapter + " : <a href='" + chapterNode.Attributes["Url"].Value + "'>" + chapterNode.Attributes["Name"].Value + "</a>"; } } // Return the string, which contains the list of chapters. return chapterString; } We explored some areas where XML can be used. But XML can be used in a very wide range of ways. We will explore more advanced uses of XML in another chapter. XML Specification We gave a very brief introduction to XML in this chapter. This chapter is meant to give a very brief introduction and we haven't covered many important aspects of XML here. We will explain most of them in some other chapters. XML has become a standard now and you can read the rules and specification for this standard here : http://www.w3.org/TR/2004/REC-xml-20040204 Web Development Introduction to HTML

Click here to download sample HTML files.

HtmlTutorial.zip

What is HTML HTML(Hypertext Markup Language) - is the language used for creating hypertext documents (web pages) and controlling how Web pages appear.

Even though it is a language, it is different from other programming languages like C++ or Java. In languages like C++ and Java, you can write complex applications and the language has its own syntax and rules. But you can use HTML to develop only web pages. Some facts about HTML HTML is plain text, composed of tags. HTML tags are always enclosed in angle-brackets ( < > ) HTML is not case sensitive, that means, it doesn't matter whether you type them in lower case or upper case. Tags typically are used in begin-end pairs. Most of the HTML tags have an open tag and a close tag: Eg: <B>...</B> <I>...</I> <FONT>...</FONT> <BODY>...</BODY> Some tags like <HTML>, <HEAD> etc are mandatory in any html file. A basic HTML file will have the following structure: <html> <head> <title>your title</title> </head> <body> your page content </body> </html> All the HTML tags in the above code is mandatory for an HTML page. You may copy and paste the above code into a file in notepad and name it test.html. Open the file in internet explorer to see how it works.

You can open any html file in notepad to see the HTML tags. Open the html file in Internet Explorer to see the output of HTML. Open the sample html files in notepad and make some changes own your own and see the changes in explorer. You can right click on any web page in internet, including this page and select the menu option 'View Source' to see the HTML used to create that web page. Right click on this page and choose the option 'View Source'. You can see teh HTML code used to create this page. Web Services Introduction to web services Webservices are services exposed over the internet. Typically, webservice is just like any other class library, written in any language. What make it a 'web service' is, it can be accessed across internet. Eventhough webservice is a new technology with a wide range of usage, it is a pretty simple concept. It doesn't require much additional knowledge to create webservices if you are already familiar with C# or

VB.Net. (Web services are not specific to .net. Even Java has web service applications, but here we are discussing only the .Net web services.) As we mentioned, web services are exposed over internet. To make this happen, it has to be hosted with a web site. Othen than hosted as part of a web site to make this visible across internet, web services have no web pages or UI. It is just a set of classes with public/private methods and properties. Web services are a group of [web] methods. Consumer applications can treat this as just another class library. Regular class libraries are located along with the same application and we can call any methods in the class libraries (assemblies). But in case of web services, the assembly is located in the internet server. The consumer application will not have direct access to the assembly. Consumer applications have to add a reference to the webservice URL and then call methods in it. The method call goes across the internet using SOAP protocal and results are returned across internet in the form of XML. The communication across internet happens transparently and the application need not know anything about this communication. Creating a simple web service If you are using VS.Net, it won't take more than 2-3 minutes to create your first webservice. Follow the steps below to create a web service: Choose New Project from VS.Net and create a C# project of type 'ASP.NET Web Service' and give the name 'MyWebService' The new project will have a default page 'Service1.asmx'. This is your first web service page. Web service pages have the extension .asmx (like asp.net pages have the extension .aspx) The code behind file 'Service1.asmx.cs' have a class 'Service1'. This is like other regular classes with the only difference that it inherits the system class System.Web.Services.WebService. This is required for web service classes. VS.Net creates a sample method for you. All you have to do is, uncomment the following method in Service1.asmx.cs // [WebMethod] // public string HelloWorld() // { // return "Hello World"; // } Note that this method is pretty much same as any other regular method. The only difference is, it has an attribute [WebMethod]. This attribute make the method visible across internet. If you remove this attribute, your application will still compile, but the consumer applications cannot call this method across internet. Ok, thats all you have to do to create a simple webservice. Build your solution and your web service is ready to be called by other applications. Create a consumer application A wide range of applications can consume the web services, including web page, other web services, windows applications etc. let us create a sample windows application and call our web service. Create a new C# Windows Application. Right click on the 'References' in the Solution Explorer, under your project name. Choose 'Web References'. Another window will open and will allow you to specify the URL of the web service to be referenced. Type the URL of your web service in the space provided for 'URL'. If you have created the web service in the local machine's default web site, the URL might be like this : http://localhost/MyWebService/Service1.asmx If you have given a different name fro the project or if you have changed the default service name, then your URL may differ. Type the URL and press enter. It will attempt to connect with the web service and if succeded it will retrieve the public web methods and display. Once you get this success screen, press the 'Add Reference' button on the screen to add the web reference to your application. There is a space to specify the 'web reference name', which will have the default value 'localhost'. Leave it as it is.

Now you are ready to make calls to the webservice. Just use the following code in your application: localhost.Service1 service = new localhost.Service1(); string result = service.HelloWorld(); MessageBox.Show( result ); Let us analyze our code. The first line creates an instance of the Service1 class, just like any regular class. Only thing is it uses the namespace 'localhost'. This is same as the 'web reference name' we specified while adding the web reference. We can use any web reference name when we add the reference and have to use the same name as namespace while making calls to the web service class. In the second line, we are actually calling the web method 'HelloWorld()' and it returns the result as a string. Note this is just like any other method call. So, your application makes the call to web service as if it is calling any local class library calls!! The communication with web service, wrapping your calls in SOAP/XML, retrieve results from web service, unwrap the SOAP/XML to get the actual result etc are done behind the scene by the framework and you need not do any additional work to make all this work. Now you can go back to your web service, add more methods with different parameters and play around with that. You will be able to call methods in the web service just like you use any local class. Note that when you make any changes to the method name or parameters, or if you add new methods, you will beed to refresh your web reference to get access to the updated web service methods. To do this, go to the Server Explorer, right click on the web reference name 'localhost' under the 'Web References'. Then choose 'Refresh'. This will communicate with the web service again and retrieve the latest web service data. How does all this work? To make calls to any classes, your application need to know the details of the class. To successfully compile your code, it has to have information about the class, what are the public methods and properties etc. But in your sample code which calls the web service, the actual Service1 class resides in the web (in your case, in your local web server). So how does the application compile without having the 'Service1' class in your application? This is where the framework help you. When you add a 'web reference' to the web service URL, VS.Net actually creates local proxy in your application. A local proxy is a minimal version of the actual class. The proxy has just the sufficient information about the 'real class', which is required for your application to successfully compile. The proxy class has the list of all public web methods in the real web service class and it knows the parameters and their data types of each method. The most important thing is, your application is actually using this proxy class and not the real web service class. localhost.Service1 service = new localhost.Service1(); string result = service.HelloWorld(); MessageBox.Show( result ); In the above code, localhost.Service1 is actually the proxy class (a representative of a real class), which is created automatically by VS.Net when you added the web reference. You are creating an instance of the proxy class and calling the 'HelloWorld()' method of this proxy. Since the proxy class knows that it is 'only a proxy of the real class', it redirects all calls to the 'real web service class'. The method 'HelloWorld()' in the proxy class takes care of converting the call to a web request using SOAP/XML. After retrieving the result of the web request to the real web service class, this proxy class takes the responsibility of parsing the SOAP/XML response and returning only the result string to the calling applicationn. So the proxy class does all the dirty job for you. The proxy class has no implementaion of the functionality. It just redirects the call to the web service. So, if you make any changes to the implementation in the web service, still you will get the 'updated result' when you make calls to web service. But, if you change the method name, or change the parameter types in the web service and do not 'refresh the web reference', then your application will compile with the old proxy. But when the proxy redirect the call to the web service, it will find that the parameters or method names do not match and it will fail. So, if there is any change in the method names or parameters, you must refresh your web reference.

We will explore more features of web services in another chapter. Please complete the follwoign feedback, if this article is incomplete or misleading. Please let us know if there is anyway we can improve this article

Best Programming Practices in .NET C# Coding Standards and Best Programming Practices Anybody can write code! And with a few months of programming experience, you can write 'working applications'. Making it work is easy, but doing it the most efficient way requires more work, than just making it work! Believe it, majority of the programmers write 'Working Code', but not 'Efficient Code'. As we mentioned in the beginning of this tutorial, do you want to become the ' Most Valued Professional' of your company? Writing 'Efficient Code' is an art and you must learn and practice it. Naming Conventions and Standards Note : Pascal Casing - First character of all words are Upper Case and other characters are lower case. Camel Casing - First character of all words, except the first word are Upper Case and other characters are lower case. Use Pascal casing for Class names public class HelloWorld { ... } Use Pascal casing for Method names public class HelloWorld { void SayHello(string name) { ... } } Use Camel casing for variables and method parameters public class HelloWorld { int totalCount = 0; void SayHello(string name) { string fullMessage = "Hello " + name; ... } } Do not use Hungarian notation to name variables. In earlier days most of the programmers liked it - having the data type as a prefix for the variable name and using m_ as prefix for member variables. Eg: string m_sName; int nAge; However, in .NET coding standards, this is not reccommended. Usage of datatype and M_ to represent member variables should not be used. All variables should use camel casing.

Use Meaningfull, descriptive words to name variables. - Do not use abbreviations. Use name, address, salary etc instead of nam, addr, sal - Do not use single character variable names like i, n, x etc. Use names like index, temp One exception in this case would be variables used for iterations in loops: for ( int i = 0; i < count; i++ ) { ... } If the variable is used only as a counter for iteration and is not used anywhere else in the loop, many people still like to use a single char variable (i) instead of inventing a different suitable name. - Do not use underscores (_) in variable names. - Namespace names should follow the standard pattern <company name>.<product name>.<top level module>.<bottom level module> File name should match with class name For example, for the class HelloWorld, the file name should be helloworld.cs (or, helloworld.vb) Indentation and Spacing Use TAB for indentation. Do not use SPACES. Comments should be in the same level as the code. Curly braces ( {} ) should be in the same level as the code outside teh braces. Use one blank line to separate logical groups of code. bool SayHello (string name) { string fullMessage = "Hello " + name; DateTime currentTime = DateTime.Now; string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString(); MessageBox.Show ( message ); if ( ... ) { // Do something // ... return false; } return true; } This code looks better, than the code shown above: bool SayHello ( string name ) { string fullMessage = "Hello " + name; DateTime currentTime = DateTime.Now; string message = fullMessage + ", the time is : " + currentTime.ToShortTimeString(); MessageBox.Show ( message ); if ( ... ) { // Do something // ... return false; } return true; } There should be one and only one single blank line between each method inside the class. The curly braces should be on a separate line adn not in the same line as if, for etc. Good: if ( ... )

{ // Do something } Not Good: if ( ... ) { // Do something } Use a single space before and after each operator and brackets. Good: if ( showResult == true ) { for ( int i = 0; i < 10; i++ ) { // } } Not Good: if(showResult==true) { for(int i= 0;i<10;i++) { // } } Good Programming practices Follow the best practices to for best programming Avoid having too large files. If a file has more than 300~400 lines of code, you must consider refactoring code into helper classes. Avoid writing very long methods. A method should typically have 1~25 lines of code. If a method has more than 25 lines of code, you must consider re factoring into separate methods. Method name should tell what it does. Do not use mis-leading names. If the method name is obvious, there is no need of documentation explaining what the method does. Good: void SavePhoneNumber ( string phoneNumber ) { // Save the phone number. } Not Good: // This method will save the phone number. void SaveData ( string phoneNumber ) { // Save the phone number. } A method should do only 'one job'. Do not combine more than one job in a single method, even if those jobs are very small. Good: // Save the address. SaveAddress ( address ); // Send an email to the supervisor to inform that the address is updated. SendEmail ( address, email ); void SaveAddress ( string address ) { // Save the address. // ...

} void SendEmail ( string address, string email ) { // Send an email to inform the supervisor that the address is changed. // ... } Not Good: // Save address and send an email to the supervisor to inform that the address is updated. SaveAddress ( address, email ); void SaveAddress ( string address, string email ) { // Job 1. // Save the address. // ... // Job 2. // Send an email to inform the supervisor that the address is changed. // ... } Use the c# or VB.NET specific types, rather than the alias types defined in System namespace. Good: int age; string name; object contactInfo; Not Good: Int16 age; String name; Object contactInfo; Do not hardcode numbers. Use constants instead. Do not hardcode strings. Use resource files. Avoid using many member variables. Declare local variables and pass it to methods instead of sharing a member variable between methods. If you share a member variable between methods, it will be difficult to track which method changed the value and when. Use enum wherever required. Do not use numbers or strings to indicate discrete values. Good: enum MailType { Html, PlainText, Attachment } void SendMail (string message, MailType mailType) { switch ( mailType ) { case MailType.Html: // Do something break; case MailType.PlainText: // Do something break; case MailType.Attachment: // Do something break;

default: // Do something break; } } Not Good: void SendMail (string message, string mailType) { switch ( mailType ) { case "Html": // Do something break; case "PlainText": // Do something break; case "Attachment": // Do something break; default: // Do something break; } } Do not make the member variables public or protected. Keep them private and expose public/protected Properties. Never hardcode a path or drive name in code. Get the application path programmatically and use relative path. Never assume that your code will run from drive "C:". You may never know, some users may run it from network or from a "Z:". In the application start up, do some kind of "self check" and ensure all required files and dependancies are available in the expected locations. Check for database connection in start up, if required. Give a friendly message to the user in case of any problems. If the required configuration file is not found, application should be able to create one with default values. If a wrong value found in the configuration file, application should throw an error or give a message and also should tell the user what are the correct values. Error messages should help the user to solve the problem. Never give error messages like "Error in Application", "There is an error" etc. Instead give specific messages like "Failed to update database. Please make sure the login id and password are correct." When displaying error messages, in addition to telling what is wrong, the message should also tell what should the user do to solve the problem. Instead of message like "Failed to update database.", suggest what should the user do: "Failed to update database. Please make sure the login id and password are correct." Show short and friendly message to the user. But log the actual error with all possible information. This will help a lot in diagnosing problems. Comments Do not write comments for every line of code and every variable declared. Write comments wherever required. But good readable code will require very less comments. If all variables and method names are meaningfull, that would make the code very readable and will not need much comments. Less lines of comments will make the code more elegant. But if the code is not clean/readable and there are less comments, that is worse. If you have to use some complex or weired logic for any reason, document it very well with sufficient comments. If you initialize a numeric variable to a special number other than 0, -1 etc, document the reason for choosing that value. The bottom line is, write clean, readable code such a way that it doesn't need any comments to understand. Do a spell check on comments and also make sure proper grammar and punctuation is used.

Exception Handling Never do a 'catch exception and do nothing'. If you hide an exception, you will never know if the exception happened or not. In case of exceptions, give a friendly message to the user, but log the actual error with all possible details about the error, including the time it occurred, method and class name etc. Always catch only the specific exception, not generic exception. Good: void ReadFromFile ( string fileName ) { try { // read from file. } catch (FileIOException ex) { // log error. // re-throw exception depending on your case. throw; } } Not Good: void ReadFromFile ( string fileName ) { try { // read from file. } catch (Exception ex) { // Catching general exception is bad... we will never know whether it // was a file error or some other error. // Here you are hiding an exception. // In this case no one will ever know that an exception happened. return ""; } } No need to catch the general exception in all your methods. Leave it open and let the application crash. This will help you find most of the errors during development cycle. You can have an application level (thread level) error handler where you can handle all general exceptions. In case of an 'unexpected general error', this error handler should catch the exception and should log the error in addition to giving a friendly message to the user before closing the application, or allowing the user to 'ignore and proceed'. Do not write try-catch in all your methods. Use it only if there is a possibility that a a specific exception may occur. For example, if you are writing into a file, handle only FileIOException. Do not write very large try-catch blocks. If required, write separate try-catch for each task you perform and enclose only the specific piece of code inside the try-catch. This will help you find which piece of code generated the exception and you can give specific error message to the user. You may write your own custom exception classes, if required in your application. Do not derive your custom exceptions from the base class SystemException. Instead, inherit from ApplicationException. Read more about Best practices and naming guidelines at Microsoft website. NET Design Patterns Design Patterns in .Net

This is an advanced topic. But if you have carefully followed all our chapters, at this stage you must be an expert programmer and its time for you to learn design patterns. What is 'Design Pattern' ? [To be added.] Various types of patterns in .Net [To be added.] ----------------------------------------------------------------------------------------------------------------------------------------Generics in C# "Generics" are the new addition to this new, powerfull language. Generics is similar to the templates in C++. ObjectSpaces Introduction to ObjectSpaces There has been several Object/Relational mapping tools in the market for quite a long time. Even after MicroSoft came up with the .NET technologies, many companies provided O/R mapping tools for .NET. Some of the O/R mapping tools for .NET include Objectz.Net, ORM.Net etc. What is Object/Relational Mapping tools ? ObjectSpaces and other OR mapping tools has it's own implementation and features, but basically they all do the same for you. It lets you map the properties and fields of your business objects directly to your database tables, columns and views. It is a framework that lets you totally avoid SQL and stored procedures. All of your data is transferred between objects and data sources transparently. That means that you can concentrate on writing business logic, not database access code. Your business objects doesn't directly depend on the datasource. It eliminates the need to embed SQL statements into business layer code and separates the business layer from database provider and schema changes which improves maintainability. Most of the OR Mapping tools come with some kinds of editors that let you map your object to the corresponding tables in the database. You will be able to drag and drop data sources like tables and views and map them graphically to your class properties and fields. So, when you use an OR Mapping model in your application, you may never need to write low level data access code like: "update USERS_TABLE set NAME='My New Name' where USER_ID = 'userid'" Instead, you will write something like this: UserObject.Name = "My New Name"; OR.Save( UserObject ); You are simply using your own class and passing it to the OR system. It will take care of updating the required tables. Does this look more object oriented ? This is what MicroSoft ObjectSpaces or any other OR tool will help you to do. We will explain Object/Relational model with small example. We are discussing the general OR modelling concepts and not any specific OR modelling tool.

In typical object oriented programming, you will have a class representing each of your database tables. In a simple scenario, suppose you have a database table called 'Employee', you may write a class corresponding to the table. public class Employee { public string Id; public public public public } Now, you have the class representing the table. Next step is mapping each field of the class with corresponding column in the table. You will use the 'mapping editor' provided by the OR mapping tool. The mapping editor will display the class fields and database table columns. You can visually connect (probably by drag and drop) class fields to the corresponding columns in the table. Once you complete this mapping between class fields and table columns, you can save the mapping. Most of the OR tools save the 'mapping' as xml files. When you run your application, this xml mapping file will be loaded. To access database, you may just need to call some methods which will return data in the form of objects. Also, you will be calling simple methods like .Insert(), .Update() etc on your object to save data back to database. You don't need to write the queries or stored procedures. The OR mapping tool will internally handle it for you based on the mapping you created between your class and table. Employee empObject = OR.GetObject( typeof(Employee), "Id = '100'" ); where 'OR' will be the class provided by your OR tool, to access the OR system. empObject.Name = "New Name"; empObject.Designation = "new designation"; empObject.Designation = "new Department"; empObject.Designation = "new Skills"; OR.Save( empObject ); The way you retrieve objects and save back to database will slightly vary from tool to tool, but the underlying concepts remain the same. Lets have a detailed look into the MicroSoft ObjectSpaces, an upcoming OR mapping tool from MicroSoft. Microsoft .NET ObjectSpaces Microsoft .NET ObjectSpaces is a new tool from MicroSoft, making the programmers life more easier. Object Spaces is an "OR Mapping tool" and includes a set of classes and interfaces that allows to treat data as an object. Like any other OR model, the data can be treated as an object, independent of the underlying data store used by an application. Microsoft's ObjectSpaces, which would be part of the next version of ADO.NET, comes with a set of new data access APIs within the Microsoft .NET Framework, under the namespace System.Data.ObjectSpaces. ObjectSpaces lets you perform the following data related tasks/steps, usually represented as CRUD (Create/Read/Update/Delete) tasks: Retrieve data as objects from a data source instead of retrieving them as dataset or record sets. Navigate one-to-many or one-to-one relationships using the objects returned, and load the related objects only when they are accessed (lazy loading). Update the values/properties of the objects string string string string Name; Designation; Department; Skills;

Save changes back to the data source Once you have defined a 'persistent object', you can use ObjectSpaces classes to create instances of your object and to persist the object data to a data store, retrieve, update, save or delete instances of the object from the data store. You may never have to write even a single line of SQL. Everything is handled internally by ObjectSpaces framework. The relationships between objects are stored in XML mapping files. Also, the relation between data source and the business objects are maintained in XML based mapping file and is separated from application. The following XML files will be created in ObjectSpaces to map object to the database. XML file, explaining the object properties. XML file explaining the database table schema XML file mapping the object properties to the datbase - this file maps the above two xmls The main class of the ObjectSpaces is 'ObjectSpace', which need to be used to instantiate and load Object mapping. The following are the main classes part of ObjectSpaces: ObjectSpace - Instantiate and load object mapping. ObjectReader - Forward-only, Read-only collection of objects. (Like a DataReader) ObjectSet - Collection of objects. (like a DataSet) ObjectQuery - Represents a query, used to retrieve data from a data source based on the query criteria. The Object Spaces toolkit also provides a simple graphical interface that can be used to map data to your classes. You will be able to browse through your datasource, drag 'n drop tables/views etc and map them to you 'objects'. The following code sample demonstrates the use of some of the ObjectSpaces classes to retrieve and persist object values. using System; using System.Data.ObjectSpaces; using System.Data.SqlClient; // // Employee Class. // public class Employee { public string Id; public public public public } // // ObjectSpaces Tutorial // public class MySample { public static void Main() { // // Create an Employee object. // Employee emp = new Employee(); string string string string Name; Designation; Department; Skills;

emp.Id = "1"; emp.Name = "Tom"; emp.Designation = "Senior Manager"; emp.Department = "Sales"; emp.Skills = "International Marketing"; // // Load in the mapping information and create the ObjectSpace. // SqlConnection conn = new SqlConnection( connectionString );

ObjectSpace os = new ObjectSpace("map.xml", conn); // // Commit the changes to the underlying object storage. // // Tell the ObjectSpaces that this is a new 'employee' object os.StartTracking( emp, InitialState.Inserted ); // This step do the actual 'insert into EMPLOYEE_TABLE ...' os.PersistChanges( emp ); // // Retrieve objects from the data source. // // Retrieve all employees of Sales department ObjectReader reader = os.GetObjectReader(new ObjectQuery(typeof(Employee), "Department = 'Sales'", ""));

foreach (Employee emp in reader) { Console.WriteLine("\n{0} - " + "\n Id: {1}" + "\n Name: {2}" + "\n Designation: {3}" + "\n Department: {4}" + "\n Skills: {5}", emp.GetType(), emp.Id, emp.Name, emp.Designation, emp.Department, emp.Skills); } reader.Close(); } } All these seem to be very interesting, right? But you need to wait until MicroSoft release them to public, along with their next version of .NET. MicroSoft is still working on enhancing the ObjectSpaces based on the user feedbacks and expert opinions. Advantages of ObjectSpaces over other O/R Mapping tools Until ObjectSpaces is publicly available and we all use it in real world applications, we cannot really say the good and bad of it. But the price would the most significant difference. As far as we know so far, ObjectSpaces come free with Visual Studio .NET. ObjectSpaces Samples Soon we will publish some examples and tutorials for MicroSoft Object Spaces. Please check back

soon. More Information There is a community site available in MSN, but at this point of time, it contains all useless postings. Hope the administrator will soon clean up and provide a better space for ObjectSpaces. http://communities.msn.com/objectspaces Links in Microsoft MSDN Site : Object Spaces in MSDN Overview of the ObjectSpaces Architecture Provides a description of the classes that make up the ObjectSpaces architecture and how they are used. Creating Classes for use With ObjectSpaces Describes how to define persistent classes and relationships and map them to a data source. Retrieving Objects from a Data Source Describes how to retrieve objects from a data source including construction of queries and streaming of objects. Persisting Objects to a Data Source Describes how to identify objects as persistent and store persistent properties at the data source. Working With the Object Engine Describes how to perform more advanced tasks using the ObjectEngine. Using ObjectSpaces with ADO.NET Describes how to use the ObjectSpaces architecture to retrieve objects from a DataReader ------------------------------------------------------------------------------------------------------------------------------------------

Anda mungkin juga menyukai