Thursday, December 17, 2009

Events


Events

To recap: in object-oriented languages, objects expose encapsulated functions called methods. Methods are encapsulated functions which run when they are invoked.
Sometimes, however, we think of the process of method invocation more grandly. In such a case, the method invocation is termed an 'event', and the running of the method is the 'handling' of the event. An archetypal example of an event is a user's selection of a button on a graphical user interface; this action may trigger a number of methods to 'handle' it.
What distinguishes events from other method invocations is not, however, that they must be generated externally. Any internal change in the state of a program can be used as an event. Rather, what distinguishes events is that they are backed by a particular 'subscription-notification' model. An arbitrary class must be able to 'subscribe to' (or declare its interest in) a particular event, and then receive a 'notification' (ie. have one of its methods run) whenever the event occurs.
Delegates - in particular multicast delegates - are essential in realizing this subscription-notification model. The following example describes how Class 2 subscribes to an event issued by Class 1.
1. Class 1 is an issuer of E-events. It maintains a public multicast delegate D.
2. Class 2 wants to respond to E-events with its event-handling method M. It therefore adds onto D a reference to M.
3. When Class 1 wants to issue an E-event, it calls D. This invokes all of the methods which have subscribed to the event, including M.
The 'event' keyword is used to declare a particular multicast delegate (in fact, it is usual in the literature to just identify the event with this delegate). The code below shows a class EventIssuer, which maintains an event field myEvent. We could instead have declared the event to be a property instead of a field  . To raise the myEvent event, the method onMyEvent is called (note that we are checking in this method to see if myEvent is null - trying to trigger a null event gives a run-time error).
1.
public class EventIssuer
2.
{
3.
    public delegate void EventDelegate(object from, EventArgs args);
4.
    public event EventDelegate myEvent;
5.
6.
    protected virtual void onMyEvent(EventArgs args)
7.
    {
8.
        if (myEvent!=null)
9.
            myEvent(this, args);
10.
    }
11.

A class which wanted to handle the events issued by an EventIssuer ei with its method handleEvents would then subscribe to these events with the code:
ei.myEvent += new EventIssuer.EventDelegate(handleEvents);

Good Practice For Events

The code above demonstrates some points about event-handling which are not enforced by the language architecture, but are used throughout the .Net framework as good practice.
1. When you want to raise an event in code, you don't tend to trigger the class's event object directly. Rather, you call a 'protected, virtual' method to trigger it (cf. the onMyEvent method above).
2. By convention, when events are raised they pass two objects to their subscribers. The first is a reference to the class raising the event; the second is an instance of the System.EventArgs class which contains any arbitrary data about the event.
3. If an event is not interested in passing data to subscribers, then its defining delegate will still reference an EventArgs object (but a null value will be passed by the event). If an event should pass data to its subscribers, however, then it is standard to use a specific class which derives from the EventArgs class to hold this data.
4. When you write a class which inherits from an event-raising base class, you can 'intercept' an event by overriding the method used to raise it. The following code illustrates such an intercept - classes which subscribe to the event will never receive notifications about it.
1.
    protected override void onMyEvent(EventArgs args)
2.
    {
3.
         Console.WriteLine("hello");
4.
    }
5.

If you want subscribers to continue to receive notifications despite such an 'intercepting' method, however, then you can call the base class method as in the following:
1.
    protected override void onMyEvent(EventArgs args)
2.
    {
3.
         Console.WriteLine("hello");
4.
         base.onMyEvent(args);
5.
    }
6.




DELEGATE



Delegates are reference types which allow indirect calls to methods. A delegate instance holds references to some number of methods, and by invoking the delegate one causes all of these methods to be called. The usefulness of delegates lies in the fact that the functions which invoke them are blind to the underlying methods they thereby cause to run (see, for instance, the discussion of events, below).
From this brief description, it can be seen that delegates are functionally rather similar to C++'s 'function pointers'. However, it is important to bear in mind two main differences. Firstly, delegates are reference types rather than value types. Secondly, some single delegates can reference multiple methods

Delegate Declaration and Instantiation

Delegates can be specified on their own in a namespace, or else can be specified within another class (the examples below all show the latter). In each case, the declaration specifies a new class, which inherits from System.MulticastDelegate.
Each delegate is limited to referencing methods of a particular kind only. The type is indicated by the delegate declaration - the input parameters and return type given in the delegate declaration must be shared by the methods its delegate instances reference. To illustrate this: a delegate specified as below can be used to refer only to methods which have a single String input and no return value:
public delegate void Print (String s);
Suppose, for instance, that a class contains the following method:
1.
public void realMethod (String myString)
2.
{
3.
    // method code
4.
}

Another method in this class could then instantiate the 'Print' delegate in the following way, so that it holds a reference to 'realMethod':
Print delegateVariable = new Print(realMethod);
We can note two important points about this example. Firstly, the unqualified method passed to the delegate constructor is implicitly recognised as a method of the instance passing it. That is, the code is equivalent to:
Print delegateVariable = new Print(this.realMethod);
We can, however, in the same way pass to the delegate constructor the methods of other class instances, or even static class methods. In the case of the former, the instance must exist at the time the method reference is passed. In the case of the latter (exemplified below), the class need never be instantiated.
Print delegateVariable = new Print(ExampleClass.exampleMethod);
The second thing to note about the example is that all delegates can be constructed in this fashion, to create a delegate instance which refers to a single method. However, as we noted before, some delegates - termed 'multicast delegates' - can simultaneously reference multiple methods. These delegates must - like our Print delegate - specify a 'void' return type.
One manipulates the references of multicast delegates by using addition and subtraction operators (although delegates are in fact immutable reference types ) The following code gives some examples:
1.
Print s = null;
2.
s = s + new Print (realMethod);
3.
s += new Print (otherRealMethod);

The - and -= operators are used in the same way to remove method references from a delegate.
The following code gives an example of the use of delegates. In the Main method, the Print delegate is instantiated twice, taking different methods. These Print delegates are then passed to the Display method, which by invoking the Print delegate causes the method it holds to run. As an exercise, you could try rewriting the code to make Print a multicast delegate.
1.
using System;
2.
using System.IO;
3.
4.
public class DelegateTest
5.
{
6.
    public delegate void Print (String s);
7.
8.
    public static void Main()
9.
    {
10.
        Print s = new Print (toConsole);
11.
        Print v = new Print (toFile);
12.
        Display (s);
13.
        Display (v);
14.
    }
15.
16.
    public static void toConsole (String str)
17.
    {
18.
        Console.WriteLine(str);
19.
    }
20.
21.
    public static void toFile (String s)
22.
    {
23.
        StreamWriter fileOut = File.CreateText("fred.txt");
24.
        fileOut.WriteLine(s);
25.
        fileOut.Flush();
26.
        fileOut.Close();
27.
    }
28.
29.
    public static void Display(Print pMethod)
30.
    {
31.
        pMethod("This should be displayed in the console");
32.
    }
33.
}

Tuesday, November 3, 2009

METHODS




A method is a member that implements a computation or action that can be performed by an object or class. Static methods are accessed through the class. Instance methods are accessed through instances of the class.
Methods have a (possibly empty) list of parameters, which represent values or variable references passed to the method, and a return type, which specifies the type of the value computed and returned by the method. A method’s return type is void if it does not return a value.
The signature of a method must be unique in the class in which the method is declared. The signature of a method consists of the name of the method and the number, modifiers, and types of its parameters. The signature of a method does not include the return type.

Parameters

Parameters are used to pass values or variable references to methods. The parameters of a method get their actual values from the arguments that are specified when the method is invoked. There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Value and Reference Parameters
  You pass value-type method parameters by value—that is, you pass a copy of the value to the method. Therefore, what the called method does with the incoming parameter doesn’t affect the variable passed down from the calling method. Consider the following simple example:
Using System;
class SomeClass
{
    public int ChangeInt(int val)
    {   val = val*2;
        return val;
    }
}

class ValRefTest
{
    static void Main(string[] args)
    {
        SomeClass sc = new SomeClass();
        int val1 = 3;
        int val2 = sc.ChangeInt(val1);
        Console.WriteLine("val1 = {0}, val2 = {1}", 
            val1, val2);
    }
}
The output from this code will be:
val1 = 3, val2 = 6
The behavior with reference-type parameters is different because what gets passed is a copy of the reference (another reference to the same data). Therefore, if the called method makes changes to the data through the reference, the changes are made to the original data. The reference held by the calling method is a reference to the same data, so the changes will be available to the calling method when the called method returns:
Using System;
class SomeClass
{
    public int ChangeInt(ref int val)
    {   val = val*2;
        return val;
    }
}

class ValRefTest
{
    static void Main(string[] args)
    {
        SomeClass sc = new SomeClass();
        int val1 = 3;
        int val2 = sc.ChangeInt(ref val1);
        Console.WriteLine("val1 = {0}, val2 = {1}", 
            val1, val2);
    }
}
The output from this code will be:
val1 = 6, val2 = 6
Let’s be clear about this process: in both cases, a copy of the parameter passes from caller to called method. If you pass a copy of a value type, you get a copy of the data. But if you pass a copy of a reference type, you get a copy of the reference. When accessing the original data, a copy of a reference is indistinguishable from the original reference.
Using out Access to Parameters
The return type enables you to send back a single variable from a method; however, sometimes you will want more than one value to be returned. Although reference variables could be used to do this, C# has also added a special attribute type specifically for returning data from a method.
You can add parameters to your method header specifically for returning values by adding the out keyword. This keyword signifies that a value is being returned out of the method but is not coming in. When you call a method that has an out parameter, you must be sure to include a variable to hold the value being returned.
using System;

 class nbr
 {
 public void math_routines( double x, out double half, out double squared,
            out double cubed )
            {
                        half = x / 2;
                        squared = x * x;
 cubed = x * x * x;
 }
 }

 class Outter
 {
            public static void Main()
 {
                        nbr doit = new nbr();

                        double nbr = 600;
 double Half_nbr, Squared_nbr Cubed_nbr;
           
 doit.math_routines( nbr, out Half_nbr,
 out Squared_nbr, out Cubed_nbr );
                        Console.WriteLine(“After method -> nbr = {0}”, nbr);
 Console.WriteLine(“ Half_nbr = {0}”, Half_nbr);
 Console.WriteLine(“ Squared_nbr = {0}”, Squared_nbr);
 Console.WriteLine(“ Cubed_nbr = {0}”, Cubed_nbr);
 }
 }
Output of the program is-
After method -> nbr = 600
Half_nbr = 300
Squared_nbr = 360000
Cubed_nbr = 216000000

Variable Number of parameters
A parameter array permits a variable number of arguments to be passed to a method. A parameter array is declared with the params modifier. Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type.
The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. They are declared as follows.
public class Console
{
            public static void Write(string fmt, params object[] args) {...}
            public static void WriteLine(string fmt, params object[] args) {...}
            ...
}
Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. However, in an invocation of a method with a parameter array, it is possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. In the latter case, an array instance is automatically created and initialized with the given arguments. This example
Console.WriteLine("x={0} y={1} z={2}", x, y, z);
is equivalent to writing the following.
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine("x={0} y={1} z={2}", args);
For instance, the example
using System;
class Test
 {
 static void F(params int[] args) {
 Console.WriteLine("# of arguments: {0}", args.Length);
 for (int i = 0; i < args.Length; i++)
 Console.WriteLine("\targs[{0}] = {1}", i, args[i]);
 }
 static void Main() {
 F();
 F(1);
 F(1, 2);
 F(1, 2, 3);
 F(new int[] {1, 2, 3, 4});
 }
 }
 shows a method F that takes a variable number of int arguments, and several invocations of this method.
 The output is:
 # of arguments: 0
 # of arguments: 1
 args[0] = 1
 # of arguments: 2
 args[0] = 1
 args[1] = 2
 # of arguments: 3
 args[0] = 1
 args[1] = 2
 args[2] = 3
 # of arguments: 4
 args[0] = 1
 args[1] = 2
 args[2] = 3
 args[3] = 4
  

Saturday, September 26, 2009

Constructors


CONSTRUCTORS
One of the biggest advantages of an object-oriented programming (OOP) language such as C# is that you can define special methods that are called whenever an instance of the class is created. These methods are called constructors. C# introduces a new type of constructor called a static constructor, which you’ll see in the next section, “Static Members and Instance Members.”
A key benefit of using a constructor is that it guarantees that the object will go through proper initialization before being used. When a user instantiates an object, that object’s constructor is called and must return before the user can perform any other work with that object. This guarantee helps ensure the integrity of the object and helps make applications written with object-oriented languages much more reliable.
But how do you name a constructor so that the compiler will know to call it when the object is instantiated? The C# designers followed the lead of the C++ language designer, Bjarne Stroustrup, and dictated that constructors in C# must have the same name as the class itself. Here’s a simple class with an equally simple constructor:
using System;

class Constructor1App
{
    Constructor1App()
    {
        Console.WriteLine("[Constructor1App.Constructor1App] " +
            "I'm the constructor");
    }

    public static void Main()
    {
        Console.WriteLine("\n[Main] Instantiating a " +
            "Constructor1 object...");
        Constructor1App app = new Constructor1App();
    }
}
Constructors don’t return values. If you attempt to prefix the constructor with a type, the compiler will issue an error stating that you can’t define a member with the same name as the enclosing type.
You should also note the way objects are instantiated in C#. This is done using the new keyword with the following syntax:
<class> <object> = new <class>(constructor arguments)
If you come from a C++ background, pay special attention to this. In C++, you can instantiate an object in two ways. You can declare it on the stack, like this:
// C++ code. This creates an instance of CMyClass on the stack.
CMyClass myClass;
Or you can instantiate the object on the free store (or heap) by using the C++ new keyword:
// C++ code. This creates an instance of CMyClass on the heap.
CMyClass myClass = new CMyClass();
Instantiating objects is different in C# than it is in C++, and this difference is a cause for confusion for new C# developers. The confusion stems from the fact that both languages share a common keyword for creating objects. Although using the new keyword in C++ lets you dictate where an object gets created, where an object is created in C# depends upon the type being instantiated.  Having said that, the following code is valid C# code, but if you’re a C++ developer, it might not do what you expect it too:
MyClass myClass;
In C++, this code would create an instance of MyClass on the stack. As mentioned, you can create objects in C# only by using the new keyword. Therefore, this line of code in C# merely declares that myClass is a variable of type MyClass, but it doesn’t instantiate the object.
As an example of this, if you compile the following program, the C# compiler will warn you that the variable has been declared but isn’t used in the application.  
using System;

class Constructor2App
{
    Constructor2App()
    {
        Console.WriteLine("[Constructor2App.Constructor2App] " +
            "I'm the constructor");
    }

    public static void Main()
    {
        Console.WriteLine("\n[Main] Declaring, but not " +
            "instantiating, a Constructor2 object..."); 
        Constructor2App app;
    }
}
Therefore, if you declare an object type, you need to instantiate it somewhere in your code by using the new keyword:
Constructor2App app;
app = new Constructor2App();
Why would you declare an object without instantiating it? Declaring objects before using them—or “new-ing“ them—is done in cases in which you declare one class inside another. This nesting of classes is called containment, or aggregation. For example, I might have an Invoice class that has several embedded classes, such as Customer, TermCode, and SalesTaxCode.
Static Members and Instance Members
As with C++, you can define a member of a class as a static member or an instance member. By default, each member is defined as an instance member, which means that a copy of that member is made for every instance of the class. When you declare a member a static member, only one copy of the member exists. A static member is created when the application containing the class is loaded, and it exists throughout the life of the application. Therefore, you can access the member even before the class has been instantiated. But why would you do this?
One example involves the Main method. The common language runtime needs to have a common entry point to your application. You must define a static method called Main in one of your classes so that the runtime doesn’t have to instantiate one of your objects. You also use static members when you have a method that, from an object-oriented perspective, belongs to a class in terms of semantics but doesn’t need an actual object—for example, if you want to keep track of how many instances of a given object are created during the lifetime of an application. Because static members live across object instances, the following code would work:
using System;

class InstCount
{
    public InstCount()
    {
        instanceCount++;
    }

    static public int instanceCount;
    // instanceCount = 0;
}

class AppClass
{
    public static void PrintInstanceCount()
    {
        Console.WriteLine("[PrintInstanceCount] Now there {0} " +
            "{1} instance{2} of the InstCount class", 
            InstCount.instanceCount == 1 ? "is" : "are",
            InstCount.instanceCount,
            InstCount.instanceCount == 1 ? "" : "s");
    }

    public static void Main()
    {
        PrintInstanceCount();

        InstCount ic;
        for (int i = 0; i < 2; i++)
        {
            ic = new InstCount();
            Console.WriteLine("[Main] Instantiated a " +
                "{0} object...", ic.GetType());

            PrintInstanceCount();
        }
    }
}

If you build and run this application, you’ll see the results shown in following Figure

One last note on static members that are value types: a static member must have a valid value. You can specify this value when you define the member, as follows:
static public int instanceCount1 = 10;
If you don’t initialize the variable, the common language runtime will do so upon application startup by using a default value of 0. Therefore, the following two lines are equivalent:
static public int instanceCount2;
static public int instanceCount2 = 0;


Constants vs. Read-Only Fields
There will certainly be times when you have fields that you don’t want altered during the execution of the application. Examples of fields you might want to protect include the names of data files your application depends on, certain unchanging values for a math class such as pi, or even server names and IP addresses that your computer connects to. Obviously, this list could go on ad infinitum. To address these situations, C# allows for the definition of two closely related member types: constants and read-only fields, which I’ll cover in this section.
Constants
As you can guess from the name, constants—represented by the const keyword—are fields that remain constant for the life of the application. There are only three rules to keep in mind when defining something as a const:
  • A constant is a member whose value is set at compile time.
  • A constant member’s value must be written as a literal.
  • To define a field as a constant, simply specify the const keyword before the member being defined, as follows:
using System;

class MagicNumbers
{
    public const double pi = 3.1415;
    public const int answerToAllLifesQuestions = 42;
}

class ConstApp
{
    public static void Main()
    {
        Console.WriteLine("CONSTANTS: pi = {0},"
           "everything else = {1}",
            MagicNumbers.pi, 
            MagicNumbers.answerToAllLifesQuestions);
    }
}

Read-Only Fields
A field defined as a const is useful because it clearly documents the programmer’s intention that the field contains an immutable value. However, that works only if you know the value at compile time. So what does a programmer do when the need arises for a field with a value that won’t be known until run time and shouldn’t be changed once it’s been initialized? This issue—typically not addressed in other languages—was resolved by the designers of the C# language with what’s called a read-only field.
When you define a field with the readonly keyword, you have the ability to set that field’s value in one place: the constructor. After that point, the field can’t be changed by the class itself or the class’s clients. Let’s say that your application needs to keep track of the current workstation’s IP address. You wouldn’t want to address this problem with a const because that would entail hard-coding the value—and even that technique wouldn’t work if the workstation obtains its IP address dynamically. However, a run-time field would do just the trick:
using System;
using System.Net;

class Workstation
{
    public Workstation()
    {
        IPAddress ipAddress =
            Dns.Resolve(HostName).AddressList[0];
        IPAddressString = ipAddress.ToString();
    }

    public const string HostName = "tyagi";
    public readonly string IPAddressString;
}

class GetIpAddress
{
    public static void Main()
    {
        Workstation workstation = new Workstation();
        Console.WriteLine("The IP address for '{0}' is {1}",
            Workstation.HostName, workstation.IPAddressString);

    }
}

Running this application will result in the display of the IP address associated with the supplied host name (tyagi). Obviously, this program won’t work correctly if you aren’t connected to a machine with a host name of “tyagi”. To specify the name of the machine to which you’re connected, simply modify the WorkStation class’s const field (HostName) to the name of the machine whose IP address you’re attempting to determine. Supply your PC’s machine name for your own workstation IP address.