FREE BOOK

Chapter 1: C# Preview

Posted by Apress Free Book | C#.NET January 08, 2009
In this chapter, I've touched upon the high-level characteristics of programs written in C#.

CLR Garbage Collection

One of the key facilities in the CLR is the garbage collector (GC). The GC frees you from the burden of handling memory allocation and deallocation, which is where many software errors can occur. However, the GC doesn't remove all resource-handling burdens from your plate, as you'll see in

  1. You can find the CLI standard document Ecma-335 at www.ecma-international.org. Additionally, Ecma-334 is
    the standard document for the C# language.
     
  2. You can find the Mono project on the Internet at www.mono-project.com.
     
  3. Of course, the target platform must also have all of the dependent libraries installed. This is quickly becoming
    a reality, given the breadth of the .NET Standard Library. For example, check out www.go-mono.com/docs/
    to see how much coverage the Mono project libraries have.
     
  4. For all the gory details, I recommend reading Don Box and Chris Sells' Essential .NET,Volume I: The Common
    Language Runtime (Boston, MA: Addison-Wesley Professional, 2002). (The title leads one to believe that Volume II is due out any time now, so let's hope it's not titled in the same vein as Mel Brooks' History of the
    World: Part I.)
Chapter 4. For example, a file handle is a resource that must be freed when the consumer is finished with it, just as memory must be freed in the same way. The GC handles only memory resources directly. To handle resources other than memory, such as database connections and file handles, you can use a finalizer (as I'll show you in Chapter 13) to free your resources when the GC notifies you that your object is being destroyed. However, an even better way is to use the Disposable pattern for this task, which I'll demonstrate in Chapters 4 and 13.

Note The CLR references all objects of reference type indirectly, similar to the way you use pointers and references in C++, except without the pointer syntax. When you declare a variable of a reference type in C#, you actually reserve a storage location that has a type associated with it, either on the heap or on the stack, which stores the reference to the object. So when you copy an object reference in one variable into another variable, you end up with two variables referencing the same object. All reference type instances live on the managed heap. The CLR manages the location of these objects, and if it needs to move them around, it updates all the outstanding references to the moved objects to point to the new location. Also, value types exist in the CLR, and instances of them live on the stack or as a field of an object on the managed heap. Their usage comes with many restrictions and nuances. You normally use them when you need a lightweight structure to manage some related data. Value types are also useful when modeling an immutable chunk of data. I cover this topic in much more detail in Chapter 4.

C# allows you to develop applications rapidly while dealing with fewer mundane details than in a C++ environment. At the same time, C# provides a language that feels familiar to either C++ or Java developers.

Example of a C# Program

Let's take a close look at a C# program. Consider the venerable "Hello World!" program that everyone knows and loves. A console version of it looks like this in C#:

 class EntryPoint
 
    {
         static void Main()
         {
             System.Console.WriteLine("Hello World!");
         }
     }

Note the structure of this C# program. It declares a type (a class named EntryPoint) and a member of that type (a method named Main). This differs from C++, where you declare a type in a header and define it in a separate compilation unit, usually a .cpp file. Also, metadata (which describes all of the types in a module and is generated transparently by the C# compiler) removes the need for the forward declarations and inclusions as required in C++. In fact, forward declarations don't even exist in C#.

C++ programmers will find the static Main method familiar, except for the fact that its name begins with a capital letter. Every program requires an entry point, and in the case of C#, it is the static Main method. There are some further differences. For example, the Main method is declared within a class (in this case, named EntryPoint). In C#, you must declare all methods within a type definition. There is no such thing as a static, free function as there is in C++. The return type for the Main method may be either of type int or void, depending on your needs. In my example, Main has no parameters, but if you need access to the command-line parameters, your Main method can declare a parameter (an array of strings) to access them.

Note If your application contains multiple types with a static Main method, you can select which one to use via the /main compiler switch.

You may notice that the call to WriteLine seems verbose. I had to qualify the method name with the class name Console, and I also had to specify the namespace that the Console class lives in (in this case, System). .NET (and therefore C#) supports namespaces to avoid name collisions in the vast global namespace. However, instead of having to type the fully qualified name, including the namespace, every time, C# provides the using directive, which is analogous to Java's import and C++'s using namespace. So you could rewrite the previous program slightly, as Listing 1-1 shows.

Listing 1-1. hello_world.cs

using System;
 
class EntryPoint
 
{
     static void Main()
     {
         Console.WriteLine("Hello World!");
     }
 }

With the using System; directive, you can omit the System namespace when calling
Console.WriteLine.

To compile this example, execute the following command from a Windows command prompt: csc.exe /r:mscorlib.dll /target:exe hello_world.cs

Let's take a look at exactly what this command line does:
  • csc.exe is the Microsoft C# compiler.
     
  • The /r option specifies the assembly dependencies this program has. Assemblies are similar in concept to DLLs in the native world. mscorlib.dll is where the System.Console object is defined. In reality, you don't need to reference the mscorlib assembly because the compiler will reference it automatically, unless you use the /nostdlib option.
     
  • The /target:exe option tells the compiler that you're building a console application, which is the default if not specified. Your other options here are /target:winexe for building a Windows GUI application, /target:library for building a DLL assembly with the .dll extension, and /target:module for generating a DLL with the .netmodule extension. /target:module generated modules don't contain an assembly manifest, so you must include it later into an assembly using the assembly linker al.exe. This provides a way to create multiple-file assemblies.
     
  • hello_world.cs is the C# program you're compiling. If multiple C# files exist in the project, you could just list them all at the end of the command line.
Once you execute this command line, it produces hello_world.exe, and you can execute it from the command line and see the expected results. If you want, you can rebuild the code with the /debug option. Then you may step through the execution inside of a debugger. To give an example of C# platform independence, if you happen to have a Linux OS running and you have the Mono VES installed on it, you can copy this hello_world.exe directly over in its binary form and it will run as expected, assuming everything is set up correctly on the Linux box.

Total Pages : 5 12345

comments