Journal Articles

CVu Journal Vol 16, #3 - Jun 2004 + Programming Topics
Browse in : All > Journals > CVu > 163 (11)
All > Topics > Programming (877)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: Introduction To C#

Author: Administrator

Date: 06 June 2004 13:16:05 +01:00 or Sun, 06 June 2004 13:16:05 +01:00

Summary: 

In this article I will focus on the basic features of the language, future articles will cover more advanced topics such as inheritance, interfaces and attributes. After reading this series of articles you will have a basis for determining if C# is for you.

Body: 

The New, New C++

C# (pronounced See Sharp), is Microsoft's latest addition to the plethora of OO (Object Oriented) programming languages available and the premiere language for developing .NET software. In this article I will focus on the basic features of the language, future articles will cover more advanced topics such as inheritance, interfaces and attributes. After reading this series of articles you will have a basis for determining if C# is for you.

The C# programming language was developed by a team of four language designers led by Anders Hejlsberg, Microsoft's Chief C# Architect. In August of 2000 Microsoft submitted C# to ECMA International where an official standards specification was developed. In addition to Microsoft's .NET implementation of the .NET platform there are several free open source alternatives such as the Mono project, www.go-mono.com.

The Example Application

In this article I will examine a fictitious address book application that stores the first and last names of contacts. The code below is the example I will review.

1  using System;
2
3  namespace Example.AddressBook
4  {
5    class Contact
6    {
7      // Internal member variables
8      string firstName;
9      string lastName;
10
11
12     Contact( string firstName, string lastName )
13     {
14       FirstName = firstName;
15       LastName = lastName;
16     }
17
18
19     // Properties
20     string FirstName
21     {
22       get { return firstName; }
23       set { firstName = value; }
24     }
25
26     string LastName
27     {
28       get { return lastName; }
29       set { lastName = value; }
30     }
31
32
33     string GetFullName()
34     {
35       return FirstName + ' ' + LastName;
36     }
37
38
39     static void Main()
40     {
41       Contact me = new Contact("Mike", "Bergin");
42       Console.WriteLine(me.GetFullName());
43       me.FirstName = "Michael";
44       Console.WriteLine(me.GetFullName());
45       Console.WriteLine(
46       new Contact("Dummy", "Value").GetFullName());
47     }
48   }
49 }

This small piece of code provides facilities for storing and retrieving a contact's first and last name and a method of determining the contact's full name.

Variables and Literals

A variable in C# is the same thing as a variable in a mathematical equation such as x = 1 + 2 . The value of x may change as the result of evaluating further lines in the equation so it is called a variable. The values 1 and 2 never change so they are called literals because they are to be taken literally. The data used by a C# application, such as a contact's first name, are stored in variables or represented by literals. A variable is analogous to a shoebox that an item may be placed in and then later retrieved from.

There are two fundamental types of data in C#, numeric and text. Numeric data represent numbers, such as 1, 2 or 84, while text data represent words such as a person's first name. The C# programming language defines 11 numeric data types, two text data types and a Boolean type. The Boolean data type is used to hold either the value true or false. The various numeric data types are listed below.

byte      decimal   double    float
int       long      sbyte     short
uint      ulong     ushort    bool

These different data types all represent numeric values however, each type implies different limitations on the values it can hold. For example the int data type can contain whole numbers in the range of -2,147,483,648 to 2,147,483,647. The float data type uses the same amount of resources as an int but can hold fractional values. For example, an int would be used to hold the number of people on a bus whereas a float would be used to represent a monetary value such as $10.50.

The two text data types defined by the C# language are char and string. The char data type represents a single character, such as the letter A. The string data type contains combinations of characters such as a person's first name. The code on lines 8 and 9 of the example declare variables of type string:

8      string firstName;
9      string lastName;

The first variable declared on line 8 is used to hold the contact's first name so it is given the identifier firstName. In the previous analogy this would be a shoebox used to hold the contact's first name. On line 9 a second variable of type string used to hold the contact's last name is declared and given the identifier lastName, same type of data but different meaning. These lines of code are commonly referred to as variable declarations. A variable declaration's basic anatomy consists of two parts, the type of data it will hold and the variable's name. In the shoebox analogy a variable declaration would be a label on the shoebox indicating what type of item it contains and what the item represents, i.e. "Tapes - Dance Music".

Methods

In C# the service a piece of code provides is referred to as a method, for example printing photographs. In the example application a method named GetFullName starting on lines 33 through 36 determines the contact's full name by combining the first and last names:

33     string GetFullName()
34     {
35       return FirstName + ' ' + LastName;
36     }

The code on line 33 is referred to as a method signature. There are two parts to this method signature, string and GetFullName. The first part of the signature indicates if the method will return any data and if so what type of data. In the case of the GetFullName method, the signature declares that it will return data of type string. Returning data means that the variable's contents will be made available to the requestor when the method completes. In this example a string containing the contact's full name will be made available to the code that called the method. The last part of the signature is the method's name, GetFullName, and is used when requesting that the method be executed.

The body of a method contains the instructions that are executed when the method is called. The GetFullName method's body consists of the lines of code between the opening and closing curly braces {}, lines 34 through 36. The body of the GetFullName method performs a very simple operation and then returns the result to the caller. The actions the method performs are outlined below.

  1. The contact's first name is retrieved.

  2. The + operator is applied to the value of the first name variable and the literal ' ' which is a single empty space character. This results in a string containing the contact's first name and a trailing space.

  3. The contact's last name is retrieved and the + operator is applied to the value resulting from the first + operation. The resulting value is a string containing the contact's first and last name separated by a single space.

  4. The value resulting from the previous three steps is then returned to the code that called the method.

The + operator, when applied to text data, performs concatenation, the combining of two strings into one. For example if the strings "First" and "Last" are concatenated the string "FirstLast" would be created. The return keyword specifies that the value following it be made available to the code that requested this method be executed.

Properties

The C# language defines a construct called a property. A property can be thought of as a method that returns and/or sets the value of a variable. The property FirstName declared on lines 20 through 24 of the example provides mechanisms for getting and setting the value of the firstName variable:

20     string FirstName
21     {
22       get { return firstName; }
23       set { firstName = value; }
24     }

The code on line 20 is a property declaration and consists of two parts, string and FirstName. The first part of this declaration is the type of data the property manages, in this case string because this property manages the firstName variable. The last part of the property declaration is the property's identifier, FirstName, the name used by code when calling this property.

The property's body is the code between the opening and closing curly braces following the property declaration, lines 21 through 24. This is very similar to methods however properties have one more level of curly braces that contain the instructions. Inside the body of a property a get and/or set code block may be defined. A code block is a generic term used to refer to code between opening and closing curly braces. If the value of the property is to be retrieved a get code block must be defined that returns the property's value. In the case of the FirstName property a get code block is defined that returns the value assigned to the firstName variable. If value of the property is to be modifiable then a set code block must be defined. In the case of the FirstName property the set code block assigns the value provided by the calling code to the firstName variable.

The code blocks defined in the body of the FirstName property are each on a single line which illustrates the important point that a line of code in C# is terminated by a semi-colon, not a return. It is therefore possible to have multiple statements on a single line as long as there are terminating semi-colon characters to divide them. A single statement may also span multiple lines but a single word may not be split between two lines. To illustrate this point the FirstName property defined on lines 20 through 24 could be written:

public string FirstName
{
  get
  {
    return _firstName;
  }
  set
  {
    _firstName = value;
  }
}

The return keyword specifies that the value following it be made available to the calling code, just as in the GetFullName method. The set code block introduces something that we haven't covered yet but before going into detail I will examine how a property is used in code. On line 43 the set code block of the FirstName property is called. Whenever a property name is followed by the assignment operator, =, the set code block is executed. The value that follows the assignment operator, in this case "Michael", is made available to the set code block as a variable named value. Just as the return keyword makes a variable available to the calling code, assigning a value to a property makes the variable following the assignment operator available to code in the set code block.

Classes and Objects

A class is a template for creating what are called objects, it defines what variables, methods, and properties objects created from the class will have. Although many objects may be created from a single class and exist at the same time, each object is unique. If a variable belonging to one object is changed the change is not reflected in other objects created from the same class.

On line 5, a class named Contact is declared:

5    class Contact

This line of code is referred to as a class declaration and is composed of two parts, class and Contact. The first part indicates that a class is being defined. The following part is the class' identifier, just like variables, methods and properties each class must have a name. The code contained between the curly braces following the class declaration is called the class definition, lines 6 through 47. The class definition contains variable, method and property declarations that define the composition of the objects created from it.

There are two main steps in the object creation process, creating a copy of the object's template, the class, and initializing the new instances. Copying the object's template is taken care of behind the scenes however, each type of object may need to be initialized differently so this logic must be provided. The initialization phase of object creation requires a specialized method called a constructor. Constructors have the same name as the class that contains them and no return type. Lines 12 through 16 contain an example of a constructor:

12     Contact( string firstName, string lastName )
13     {
14       FirstName = firstName;
15       LastName = lastName;
16     }

This constructor has what looks like two variable declarations between the parentheses following the constructor's name, line 12. These two variable declarations are called parameters. Parameters provide a mechanism for making variables available to a method's body, in this case the constructor's body. The values passed to the constructor can be accessed from within the constructor's body, the code block on lines 13 through 16. This is similar to both the return keyword and how data is made available to the set code blocks of properties.

Classes are multifaceted; they act as templates that define the variables, methods and properties of objects created from them as well as having variables, methods and properties of their own.

Namespaces

A namespace is a scope defined by the programmer that limits the visibility of elements, such as classes, declared within it. To simplify this idea let's look at how we as humans identify ourselves. In most cultures people are given at least two names, a surname and a given name. Our surnames provide a scope, and imply a relationship between the people within that scope, it is the namespace. My given name provides a unique identifier for me within the scope of my family, or namespace. If I were assigned only one name, let's say my given name Michael, how would you be able to tell me apart from other Michaels? Due to the sheer number of names and that we have at least two of them there are a huge number of possible combinations, cutting down on the possibility that you will run into someone with the same surname and given name. In programming this is used so that you and another programmer don't accidentally use the same name because then how would the computer know which item you are referring to.

In our example application the Contact class is defined in the namespace Example, making its full name, what is referred to as a FQN (Fully Qualified Name), Example.Contact. The namespace declaration is on line 3 and everything contained within the curly braces following the declaration is contained within the Example namespace:

3  namespace Example.AddressBook

If code in another namespace wanted to reference the Contact class the program would have to provide the FQN Example.Contact. Namespace identifiers can become very long so to save keystrokes C# provides a mechanism called importing. Importing makes all of the elements defined within a specific namespace available without having to provide their FQNs. This is illustrated on line 1:

1  using System;

On line 1 we declare that the code in this file would like to import the System namespace, which contains many fundamental .NET classes. All of the code contained within the Contact.cs file can now reference all of the classes contained in the System namespace without having to use their FQNs. One drawback of importing a namespace is that if you declare a class with the same name as one of the classes in the imported namespace you must still use their respective FQNs to uniquely identify them. So if there was a class named Contact in the System namespace we would need to refer to it as System.Contact and the class in the example as Example.Contact even though the System namespace is imported.

Execution

When a C# application is loaded the computer needs to know what instruction it should execute first. Execution of all C# application begin with a call to a static method named Main. When all of the instructions in the Main method have been executed the application exits. The Main method is referred to as the executable's entry point. The example application contains an entry point defined on lines 39 through 46. As you'll notice the method is named Main and is declared to be static.

39     static void Main()
40     {
41       Contact me = new Contact("Mike", "Bergin");
42       Console.WriteLine(me.GetFullName());
43       me.FirstName = "Michael";
44       Console.WriteLine(me.GetFullName());
45       Console.WriteLine(
46       new Contact("Dummy", "Value").GetFullName());
47     }

The first line of the Main method defines a variable named me of type Contact. In the previous section we discussed the concept how objects are created from classes, this is how it is done in code. The constructor being called, defined on lines 12 through 16, declares that it accepts two parameter of type string. In this particular call the parameters to the Contact constructor are set to Mike and Bergin. The constructor's body assigns these two values to the FirstName and LastName properties.

The next line calls a static method named WriteLine on a class named Console. The Console class is contained in the System namespace that was imported so there is no need to use its FQN, System.Console. If we hadn't imported the System namespace this statement would be:

System.Console.WriteLine(me.GetFullName());

The WriteLine method of the Console class accepts a single parameter of type string. This method prints whatever string value it is passed to the console. In this case we pass the string value returned by calling the GetFullName method on the object referenced by the me variable. The result of this method call will be the string Mike Bergin because these are the values passed to the constructor on the previous line.

In the next statement we change the value contained by the FirstName property of the object referenced by the me variable. The value Michael is assigned to FirstName causing the property's set code block to be executed which storing the value following the assignment operator in the firstName variable.

Now that the FirstName property has been modified a different string will be printed to the console. The FirstName property was set to Michael but the LastName property was left unmodified. Calling the GetFullName method on the me variable again now returns the value Michael Bergin, reflecting the change to the FirstName property.

The last two lines of the Main method illustrate two features of C#, the ability to chain method calls and to split a single statement between two lines. The first portion of this statement calls the WriteLine method on the Console class. On this next line another object of type Contact is created, this time passing the values Dummy and Value to the constructor. Immediately following the call to the constructor is a call to the GetFullName method, illustrating how methods may be chained together alleviating the need to explicitly define a variable. The C# language is interpreted from left to write just as the English language is read so in this case the call to the Contact constructor returns a new instance of the Contact class, then GetFullName is called on the new instance. The value returned by this series of calls is the string Dummy Value. Since this is the last statement in the Main method the application exits.

Running the Example

In order to run the sample application the source code file Contact.cs must be created and then compiled. C# is a case sensitive language so the exact case used in the example must be preserved. The line numbers are to aid in the explanation of the code and should not be included in the source code file. The file can be created using a standard text editor such as vi or emacs on Unix and notepad on Windows. Once the source code file has been created it needs to be compiled.

In order to compile the software a .NET development framework must be installed. The Mono project, www.go-mono.com, provides a free open source .NET development framework with support readily available via mailing lists and IRC chats. Mono is available for Unix like systems and Microsoft Windows allowing developers to work with the same tool chain regardless of operating system. If you're an experienced Visual Basic programmer the Mono project has a VB.NET compiler as well.

The C# compiler distributed with the Mono .NET development framework is named mcs. To compile the example application execute the compiler passing the name of the source code file as a command line argument:

mcs Contact.cs

When the compiler has finished a message such as "Compilation succeeded" will be printed to the console and the compiler will exit. Now that the source code is compiled you can run the example application by running the mono executable passing the name of the compiled executable, Contact.exe, as a command line argument:

mono Contact.exe

Summary

This article introduced the basics of the C# programming language. In the next article I will cover classes and objects in greater detail illustrating how different portions of code cooperate to perform a use service. For errata and other information visit www.mijobee.com. Please email me with any comments or suggestions at .

Acknowledgments

Special thanks to Paul Grenyer for his invaluable feedback.

Notes: 

More fields may be available via dynamicdata ..