This tutorial explains the basics of C#, a modern Object Oriented Programming language that was designed by Anders Hejlsberg at Microsoft.
A QUICK INTRODUCTION
The pursuit to teach any new language usually begins with the classic Hello World program. This tutorial does not break that tradition.
/*
* HelloWorld.cs
* Version 1.1
* A program that prints Hello, world! on screen
*/
class HelloWorld
{
public static void Main()
{
System.Console.WriteLine("Hello, world!");
}
}
Compiling and running
There are currently two approaches to compiling and running this program. The more rugged solution would be to download the Microsoft.NET platform SDK, from microsoft.com and compile it using the C# command line compiler. This produces an Intermediate Language .exe that can be executed from the console. The second and more costly option would be to purchase Microsoft Visual Studio. It has a neat IDE in which the preceding program could be compiled under a new Solution. The Express Edition of Visual Studio is available for free.
Using the first option, use the following command:
csc HelloWorld.cs
The following is the result of that command:
Microsoft (R) Visual C# Compiler Version [CLR version]
Copyright (C) Microsoft Corp 2000-2001. All rights reserved.
In this admittedly simple case, you do not need to specify anything other than the file to compile. In particular, C# does not use the additional step of linking that is required by unmanaged comilers such as C/C++.
The default output of the C# compiler is an executable file of the same name, and running this program generates the following output:
C:\\HelloWorld\cs>HelloWorld
Hello, world!
Programmers familiar with Java will be amazed at how close the C# syntax is to Java. As in C, C++ and Java, "//" delimts commens in a line and "/*" and "*/" surround comment lines in C# also. Any line started by "//" or contained within "/*" ... "*/" is ignored by the compiler. However in C#, XML statements may be embedded within comments and may later be used to generate documentation for the program.
Just as the entry point to a C/C++/Java program is "main", the entry point to a C# program is Main() with a capital M. But unlike the former, no arguments are passed to Main(), and it returns a void (a keyword that indicates the function does not return anything).
"public" and "static" are required qualifiers for the entry point function Main(). More on this later.
From the Official Documentation:
"The compiler requires the entry point to be called Main. The entry point must also be marked with both public and static. In addition, the entry point takes no arguments and does not return anything (although different signatures for more sophisticated programs are certainly possible)."
Since C# is strictly an Object Oriented language, there needs to be at least one class in every program. In HelloWorld.cs the class that contains Main() is given the name HelloWorld (Note that the class name and the file name need not match. This program can be put into a file called myFirstProgram.cs. It will compile and run properly even then).
From the Official Documentation:
"In C#, all code must be contained in methods of a class. So, to house the entry-point code, you must first create a class. (The name of the class does not matter here)."
For those familiar with C/C++/Java programming, System.Console.WriteLine() appears to be a function call. It is! It takes one argument and displays it on the console.
NAMESPACES
Namespaces were used earlier in C++ and now in C#. Namespaces, as the name suggests are spaces (areas) that are used to contain a set of programming entities such as classes, methods and so on.
From the Official Documentation:
"C# programs are organized using namespaces. Namespaces are used both as an "internal" organization system for a program, and as an "external" organization system-a way of presenting program elements that are exposed to other programs."
This has several advantages...
In a large project, two peole working on it may name a class similarly and that may lead to ambiguity. Namespaces offer a neat solution. Any number of independent programmers may use the same name to classes they create, provided they put everything into their own unique namespace.
For example, there could be a two namespaces called Console and GUI. Both could contain a function named PutText() that displays text in the command line in the case of the former and in a window in the case of the latter. Such functions could be accessed by saying Console.PutText() for the console version and GUI.PutText() for the other.
The preceding example was a generic programming example. In C# since every method needs to reside within a class, different namespaces could contain different classes with the same names.
Getting back to HelloWorld.cs, I said at the end of the previous section that System.Console.WriteLine() is a function call. Well, it is only partly true. Actually "System" is a namespace that contains a class called "Console", and Console contains a static method called WriteLine().
A Quick note on static methods:
When a class contains a method, it cannot be accessed, like a normal C style function. It needs to be invoked using an object defined as an instance of that class. But it is often required that some methods of a class be accessed without an object. To define such functions we include a qualifier called static. That explains why static is added to the Main() function. The CLR needs to call Main(), the entry point without creating any object for it.
The .NET Framework defines more than 90 namespaces within the System namespace. System contains a class called Console that mostly contains methods that are related to console operations.
Since HelloWorld.cs only contains one statement that calls the WriteLine() method in the Console class, we fully qualified it using the namespace name. Class name . Method name Image we were to make a thousand calls to it from our program. It would be tedious to reference the method using the Namespace name every time. For this purpose C# includes a keyword called "using". Let's now re-write the same example.
/*
* HelloWorld.cs
* Version 1.2
* A program that prints Hello, world! on screen
*/
using System;
class HelloWorld
{
public static void Main()
{
Console.WriteLine("Hello, world!");
}
}
The preceding program explains clearly, the purpose of "using". You specify a namespace only once in the using statement and then avoid typing the namespace name to refer to classes that come under it. In the preceding program the amount of typing avoided may seem to be trivial. Just imagine you were using the namespace "System.Windows.Forms", or your own namespace called "ProgramminginCSharp.MyPrograms.Introduction".
From the Official Documentation:
"'Using' directives facilitates the use of namespaces and types defined in other namespaces. Using directives impact the name resolution process of namespace-or-type-names (Section 3.8) and simple-names (Section 7.5.2), but unlike declarations, using directives do not contribute new members to the underlying declaration spaces of the compilation units or namespaces within which they are used."
All along I've been talking about, putting classes into namespaces. But in the two versions of our program HelloWorld.cs, our class has not been put in any namespace. What happens then? They go into the global namespace. Let's now try to write version 3 of this program that uses namespaces profitably.
/*
* HelloWorld.cs
* Version 1.3
* A program that prints Hello, world! on screen
*/
using System;
namespace CSharpTutorial
{
class HelloWorld
{
public static void Main()
{
Console.WriteLine("Hello, world!");
}
}
}
Just enclose the class within a namespace called CSharpTutorial. Just as you access pre-defined classes like System.Console, you can access this class from other programs by referring to it as CSharpTutorial.HelloWorld (this class is featureless however, to be accessed by other classes).
Namespaces also play an important role in the organization of the .NET Framework documentation. All the classes have been organized by the Namespaces under which they have been grouped.
A sample that accompanies the .NET Framework SDK itself is a command-line type locater that supports substring searches. You can use it to explore classes contained in the various namespaces. (Java developers will find it similar to javap). To build and use this sample, follow the instructions contained in the Readme.htm file that is located in the InstallDirectory\Samples\Applications\TypeFinder subdirectory.
Here is an example of how to use the type finder:
C:\\TypeFinder\CS>findtype String
class System.IO.StringWriter
That concludes the tutorial. Hope you got a feel of C#!