FREE BOOK

Chapter 1: Introduction to C#

Posted by Apress Free Book | C# Language December 08, 2008
This Chapter will introduce you to C#. You will learn how to write and compile C# programs, C# syntaxes, data types, control flow, classes and their members, inter-faces, arrays, and exception handling I'll begin with an overview of the language.

Classes

You saw a class structure in the "Hello, C# World!" sample. In the C#, you define a class by using the class keyword, just as you do in C++. Following the class keyword the class name and curly brackets ({. . .}), as shown here:

class Hello
{
          static void Main()
          {
                   Console.WriteLine("Hello, C# World!");
      }
}

Note: C# classes don't end semicolon (;) as C++.

Once a class is defined, you can add class members to it. Class members can include constants, fields, methods, properties, indexers, events, operators, instance constructors, static constructors, destructors, and nested type declarations. Each class member has an associated accessibility, which controls the scope of the member and defines whether these members are accessible outside the class.

Class Members

Table 1-9 describes allowable class member elements.

Table 1-9 allowable class member elements

CLASS MEMBER INHERITANCE
Methods Similar to C++ functions. Methods implement some action that can be performed by an object.
Properties Provide access to a class attribute (a field). Useful for exposing fields in components.
Events Used to provide notification.
Constants Represents a constant value.
Fields Represents a variable of the class
Operators Used to define an expression (+, *,->, ++,[], and so on ).
Instance Constructors Methods called during initialization of an object.
Static Constructors Called automatically.
Destructors Called when an object is being destroyed.
Indexers A new concept in C#. An indexer provider indexing on an object. It allows you to treat a class as an array.
Types All local types used in a class.

Before examining these members in detail, you'll look at the accessibility of these members. Table 1-10 describes class member accessibility type and their scopes.

Table 1-10. Class member accessibility types and scopes

ACCESSIBLITY TYPE SCOPE
Public Member is accessible from other programs.
Protected Member is accessible by the containing and its derived classes and types.
Internal Member is accessible only the current program.
Protected internal Member is accessible by the current program and the class derived from the containing class.

Now you'll look at class members in more detail.

Fields

A field member Represent a variable of a class. In this example, strClassName is a string type public variable that can be accessed by the class instance:

class
myClass
                   {
                             public static string strClassName;
                             public void SetClassName(string strName)
                             {
                                      strClassName = strName;
                             }
                   }

As noted earlier; you can define field members as read-only. This means the field can only be assigned in the declaration or in the constructor of the class. See the following code:

class myClass
{
          public static readonly string strClassName = "myClass";
          public void SetClassName(string strName)
          {
                   strClassName = strName; // illegal assignment
          }
}


Note that the complier will throw an error because of an illegal assignment.

If the field is not static, you have to access fields from the class instance. It's the same idea as accessing a public variable in the C++ or structure in C. for example:

myClass cls = new MyClass();

string clsName = cls.strClassName;

Constants

A constant Member represents a constant value throughout the program. For example the clsNodes is constant that has integer value 12. See the following code:

class myClass
{
          public const int clsNodes = 12;
}

The value of clsNodes will be 12 throughout the program and can't be reassigned.

Instance and Static Constructors

Constructors in C# are defined in the same way as in C++. C# supports two types of constructors: instance constructors and static constructors. Instance constructors are called every time a class is initialized. Static constructors are executed only once. Static constructors are for initialing the values of static variable. Listing 1-25 is an example of a class with a static constructor.

Listing 1-25 Calling Static Constructors

using System;
class myClass
{
          static myClass()
          {
                   Console.WriteLine("Initialieze clas ");
          }
          public static void foo()
          {
                   Console.WriteLine(" foo");
          }
}
class Test
{
          static void Main()
          {
                   myClass.foo();
//class myClass static constucter and then foo
          }
}

Constructors can be overloaded, as shown in listing 1-26.

Listing 1-26. Over loaded Constructors example

class myClass
{
    public int iCounter, iTotal;
    public myClass()
    {
        iCounter = 0;
        iTotal = 0;
    }
    public myClass(int iCount, int iTot)
    {
        iCounter = iCount;
        iTotal = iTot;
    }
}


Listing 1-27. Calling class constructors

using System;
class myClass
{
          public int iCounter, iTotal;
          public myClass()
          {
                   iCounter = 0;
                   iTotal = 0;
          }
          public myClass(int iCount, int iTot )
          {
                   iCounter = iCount;
                   iTotal = iTot;
          }
}

class TestmyClass
{
          static void Main()
          {
                   myClass cls = new myClass();
                   myClass cls1 = new myClass(3, 4);
                   Console.WriteLine(cls1.iCounter.ToString());
                   Console.WriteLine(cls1.iTotal.ToString());
          }
}

Destructors

A destructor is called when it's time to destroy the object. Destructors can't take parameters. See following code:

class myClass
{
 ˜ myClass()
 {
 // free resources
 }
}

TIP: It's not compulsory_ in fact it's unadvisable_ to call destructors. They're called automatically by the CLR when it destroys the object during garbage collection.

Methods

A method is a member that implements some functionality. It's similar in appearance to the methods found in C++ and java. A method can return a value have, a list of parameters, and can be accessed through the class, whereas non - static. Static methods are accessed through the class, whereas non-static methods are accessed through the instance of the class. For example, listing 1-28 adds a method sum to the class myClass and called this method from the Main method.

Listing 1-28 Class method example

using System;
class myClass
{
    public int Sum(int a, int b)
    {
        int res = a + b;
        return res;
    }
}
class TestmyClass
{
    static void Main()
    {
        myClass cls = new myClass();
        int total = cls.Sum(5, 8);
        Console.WriteLine(total.ToString());
    }
}


Methods in C# support function overloading in a similar way as C++. If you have programmed in C++, you'll notice that C# methods are similar to C++ functions (and almost mirror those methods found in java). So it's not a bad idea to call function overloading in C# method overloading. In listing 1-29, I over- overload the Sum method by passing in different types of values and call each of the overloaded Sum methods from the Main method.

Listing 1-29 Method overloading example

using System;
class myClass
{
          public int Sum(int a, int b)
          {
                   int res = a + b;
                   return res;
          }
          public float Sum(float a, float b)
          {
                   float res = a + b;
                   return res;
         }
          public long Sum(long a, long b)
          {
                   long res = a + b;
                   return res;
          }
          public long sum(long a, long b, long c)
          {
                   long res = a + b + c;
                   return res;
          }
          public long Sum(int[] a)
         {
                   int res = 0;
                   for (int i=0; i < a.Length; i++)
                   {
                             res += a[i];
                   }
                   return res;
          }
          public void Sum()
          {
                   //return nothing
          }
}
class TestmyClass
{
          static void Main()
          {
                   myClass cls = new myClass();
                   int intTot = cls.Sum(5,8);
                   Console.WriteLine("Return integer sum:"+ intTot.ToString());
                   cls.Sum();
                   long longTot = cls.Sum(Int64.MaxValue - 30, 8);
                   Console.WriteLine("Return long sum:" + longTot.ToString());
                   float floatTot = cls.Sum(Single.MaxValue-50, 8);
                   Console.WriteLine("Return float sum:" + floatTot.ToString());
                   int[] myArray = new int[] {1,3,5,7,9};
                   Console.WriteLine("Return sum of array = {0}",
                             cls.Sum(myArray).ToString());
          }
}

The ref and out Parameters

Did you ever need your method to return more than one value? You may need to do this occasionally, or you may need to use the same variables that you pass as an argument of the method. When you pass a reference type, such as a class instance, you don't have to worry about getting a value in a separate variable because the type is already being passed as a reference and will maintain the changes when it returns. A problem occurs when you want the value to be returned in the value type. The ref and out parameters help to do this with value types.

The out keyword defines an out type parameter. You Use the out keyword to pass a parameter to a method. This example is passing an integer type variable as an out parameter. You define a function with the out keyword as an argument with the variable type:

myMethod(out int iVal1)

The out parameter can be used to return the values in the same variable passed as a parameter of the method. Any changes made to the parameter will be reflected in the variable. Listing 1-30 shows an example of the parameter.

Listing 1-30. Using the out parameter

using System;
public class myClass
{
          public static void ReturnData(out int iVal1, out int iVal2)
                    {
                              iVal1 = 2;
                              iVal2 = 5;
                    }
          public static void Main()
          {
                   int iV1, iV2; // variable need not be initialized
                   ReturnData(out iV1, out iV2);
                   Console.WriteLine(iV1);
                   Console.WriteLine(iV2);
          }
}

The ref keyword defines a ref type parameter. You pass a parameter to a method with this keyword, as in listing 1-31. This example passes an integer type variable as a ref parameter. This is a method definition:

myMethod(ref int iVal1)

You can use the ref parameter as a method input parameter and an output parameter. Any changes made to the parameter will be reflected in the variable. See listing 1-31

Listing 1-31. A ref parameter example

using System;
public class myClass
{
    public static void ReturnData(ref int iVal1, ref int iVal2, ref int iVal3)
    {
        iVal1 += 2;
        iVal2 = iVal2 * iVal2;
        iVal3 = iVal2 + iVal1;
    }
    public static void Main()
    {
        int iV1, iV2, iV3; // variable need not be initialized
        iV1 = 3;
        iV2 = 10;
        iV3 = 1;
        ReturnData(ref iV1, ref iV2, ref iV3);
        Console.WriteLine(iV1);
        Console.WriteLine(iV2);
        Console.WriteLine(iV3);
    }
}

In this method, ReturnData takes three values as input parameters, operates on the passed data returns the result in the same variable.

Properties

Other than methods, another important set of members of a class is variables. A variable is a type that stores some value. The property member of a class provides access to variables. Some examples of Properties are font type, color, and visible properties. Basically, Properties are fields. A field member can be accessed directly, but a property member is always accessed through accessor and modifier methods called get and set, respectively. If you have ever created active X controls in C++ or visual basic, or created javaBeans in java, you understand.

Note: Visual Basic programmers will note that Let is not available in C#
This is because all types are objects, so only the set access or is necessary.

In Listing 1-32 you create two properties of myClass:Age and MaleGender. Age is an integer property, and MaleGender is a Boolean type property. As you can see in the example, the get and set keywords are used to get and set property values. You're reading and writing property values from the Main method. Note that leaving out the set method in a property makes the property read-only.

Listing 1-32. Class property member example

using System;
class myClass
{
          private bool bGender;
          private int intAge;
          // Gender property.
          public bool MaleGender
                  {
                   get
                   {
                             return bGender;
                   }
                   set
                   {
                             bGender = value;
                   }
          }
          // Age property
          public int Age
          {
                   get
                   {
                             return intAge;                   }
                   set
                   {
                             intAge = value;
                   }
          }
}
class TestmyClass
{
          static void Main()
          {
                   myClass cls = new myClass(); 
                   // set properties values
                   cls.MaleGender = true;
                   cls.Age = 25;
                   if (cls.MaleGender)
                   {
                             Console.WriteLine("The Gender is Male");
                             Console.WriteLine("Age is" + cls. Age.ToString() );
                   }
          }
}

Why use properties if you already have the field available? First of all, properties expose fields in classes being used in components. They also provide a means for doing necessary computation before or after accessing or modifying the private fields they're representing. For example, if you're changing the color of a control in the set method, you may also want to execute an invalidate method inside the set to repaint the screen.

Events

In C# events are a special type of delegate. An event member of a class provides notifications from user or machine input.

A class defines an event by providing an event declaration, which is of type delegate. The following line shows the definition of an event handler:

public delegate void EventHandler(object sender, System.EventArgs e);

The EventHandler takes two arguments: one of type object and the other of type System.EvenArgs. A class implements the event handler using the event keyword. In the following example, MyControl class implements the EventHandler:

public class MyControl
{
public event EvenHandler Click;
 
          public void Reset()
          {
       Click = null;
      }
}

You probably know that Windows is an event- driven operating system. In Windows programming, the system sends messages to the massage queue for every action taken by a user or the system, such as mouse-click, keyboard, touch screen, and timers. Even if the operating system is doing nothing, it still sends an idle message to the message queue after a certain interval of time.

Although you usually use events in GUI applications, you can also implement events in console-based application. You can use them when you need to notify a state of an action. You'll have a look at an example of both types.

Listing 1-33 shows you how to implement events and event handlers in a console-based application. The Boiler.cs class defines the BoilerStatus event. The SetBoilerReading method sets the boiler temperature and pressure readings, and it writes the boiler status on the console based on the temperature and pressure reading. Boiler.cs defines BoilerStatus using the event keyword.

Listing 1-33 Boiler.cs

namespace BoilerEvent
{
          using System;
          public class Boiler
          {
                   public delegate void EngineHandler(int temp);
                   public static event EngineHandler BoilerStatus;
                   public Boiler()
                   {
                   }
                   public void SetBoilerReading(int temp, int pressure)
                   {
                   if (BoilerStatus != null)
                   {
                   if (temp >=50 && pressure >= 60)
                                      {
                   BoilerStatus(temp);
                   Console.WriteLine("Boiler Status: Temperature High");
                                      }
                  else if (temp < 20 || pressure < 20)
                   {
                   BoilerStatus(temp);
                   Console.WriteLine("Boiler status: Temperature Low");
                                      }
                   else
                   Console.WriteLine("Boiler status: Temperature Normal");
                             }
                   }
          }
}

Listing 1-34 is a caller class (main application) that calls the event through BoilerEventSink. The BoilerTempoMeter method of the sink generates a warning massage on the console only when the temperature of the boiler is zero.

Listing 1-34. Caller of Boiler.Cs

namespace BoilerEvent
{
          using System;
         public class Boiler
          {
                   // Boiler class here
          }
          public class BoilerEventSink
          {
                   public void BoilerTempoMeter(int temp)
                    {
                    if (temp <= 0)
                                       {
 Console.WriteLine("Alarm: Boiler is switched off");
           }
           }
          } 
          // Event caller mailn application
          public class BoilerCallerApp
          {
                   public static int Main(string [] args)
                   {
                             Boiler boiler1 = new Boiler();
                             BoilerEventSink bsink = new BoilerEventSink();
                             Boiler.BoilerStatus += new Boiler.EngineHandler( bsink.BoilerTempoMeter);
                             boiler1.SetBoilerReadings (55, 74);
                             boiler1.SetBoilerReadings (0, 54);
                             boiler1.SetBoilerReadings (8, 23);
                             return 0;
                   }
          }
}

As you can see in Listing 1-34, I created a Boiler object that calls the BoilerStatus handler, which passes BoilerEventSink's methods as an argument when calling Boiler. EngineHandler is a delegate defined in the Boiler class. Then the program calls the SetBoilerReading method with different temperature and pressure reading. When the temperature is zero, the program displays a warning message on the console; otherwise, the program displays message generated by the SetBoilerReading method.

Actually, it's easier to understand events using windows application than it is using a console-based application. To show you can an event sample in windows Forms, you'll create a Windows application. In this application, you'll create a form and a button. The button-click event executes and displays a message box.

Here, the button-click event executes button1_click method:

button1.Click += new System.EventHandler(button1_ Click);

and the button-click handler looks like the following:

private void button1_click(object sender, System.EventArgs e)
{
MassageBox.Show ("button is clicked");
}

Listing 1-35 shows a windows forms program with event sample. If you compile this program, the out put looks like figure 1-8.

Listing 1-35. Event Handling example
using System;
using System.Windows.Forms;
using System.Drawing;
namespace NotePadWindowsForms
{
          public class NotePadWindowsForms: System.Windows.Forms.Form
          {                   private System.Windows.Forms.Button button1;
                   public NotePadWindowsForms()
                   {
                             button1 = new System.Windows.Forms.Button();
                             // Button control and its properties
                             button1.Location = new System.Drawing.Point(8, 32);
                             button1.Name ="button1";
                             button1.Size = new System.Drawing.Size(104,32);
                             button1.TabIndex = 0;
                             button1.Text = "Click me"
                             // Adding controls to the form
                             Controls.AddRange(new System.Windows.Forms.Control[]
{button1} );
button1.Click += new System.EventHandler(button1_Click);
                   }
// Button click handler
private void button1_Click(object sender, System.EventArgs e)
                   {
                             MessageBox.Show ("Button is clicked");
                   }
                   public static int Main()
                   {
                             Application.Run(new NotePadWindowsForms());
                             return 0;
                   }
          }
}

Figure 1-8 shows the output of listing 1-35 after clicking the Click me button.




Figure 1-8 output of listing1-35

Indexers

Indexers are a new concept in C#. Indexers enable a class object to function as an array. Implementing indexers is similar to implementing properties using the get and set functions. The only different is that when you call an indexer, you pass an indexing parameter. Accessing an indexer is similar to accessing an array. Indexers are nameless, so the this keyword declares indexers.

I just said that after defining indexers, a class object could be treated as an array. What does that mean? To explain, I'll show you an example using the class called my class. The way you treat an instance of myClass now is like this:

myClass cls = new myClass();
cls.MaleGender = true;

After defining an indexer in myClass, you could treat an instance of it as if it were an array:

myClass cls = new myClass();
cls[0].MaleGender = true;
cls[1].MaleGender = true;

You define indexer by using the this keyword as if were an array property of type object.
Listing 1-36 shows the indexer signature of my class.

Listing 1-36. Indexers of myClass

public object this[int index]
    {
        get
        {
            if (!ValidIndex(index))
                throw new Exception("Index out of range.");
            else
                return MaleGender(index).Value;
        }
        set
        {
            if (!ValidIndex(index))
                throw new Exception("Index out of range.");
            else
                MaleGender(index).Value = value;
        }
    }


Inheritance

Inheritance is one of the main features of an object-oriented language. C# and the .NET class library are heavily based on inheritance. The telltale sign of this is that all .NET common library classes are derived from the object class, discussed at the beginning of this article. As pointed out, C# doesn't support multiple Inheritance. C# only supports single inheritance; therefore, all objects are implicitly derived from the object class.

Implementing inheritance in C# is similar to implementing it in C++. You use a colon (:) in the definition of a class to derive it from another class. In listing1-37, BaseClassB, which later accesses the BaseClassA method in the Main method.

Listing 1-37. Inheritance example

using System;
// Base class A
class BaseClassA
{
          public void MethodA()
          {
          Console.WriteLine("A Method called");
          }
}
// Base class B is derived from Base class A
class BaseClassB:BaseClassA
{
public void MethodB()
{
Console.WriteLine("B method called");}
}
class myClass
{
static void Main()
{
// Base class B
BaseClassB b = new BaseClassB();
// Base class B method
b.MethodB();
// BaseClassA Method through BaseClassB
b.MethodA();
}
}

Total Pages : 10 678910

comments