Thursday, June 13, 2013

C# Delegates



A delegate is a C# language element that allows you to reference a method. A delegate is a reference type variable that holds the reference to a method. The reference can be changed at runtime. A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked. Unlike function pointers in C or C++, delegates are object-oriented, type-safe, and secure.

Delegates are especially used for implementing events and the call-back methods. All delegates are implicitly derived from the System.Delegate class.
A delegate type maintains three important pices of information :
  1. The name of the method on which it make calls.
  2. Any argument (if any) of this method.
  3. The return value (if any) of this method.
Declaring Delegates
Delegate declaration determines the methods that can be referenced by the delegate. A delegate can refer to a method, which have the same signature as that of the delegate.

Syntax for delegate declaration is:
delegate <return type> <delegate-name> <parameter list>

Example:
using System;   
 
delegate void MyDelegate();
 
public class MyApp
{
    static void Main()
    {
        MyDelegate delegate1 = new MyDelegate(MyFunction);
        delegate1();
    }
 
    static void MyFunction()
    {
        Console.WriteLine("Calling MyFunction");
    }
}
We declare a delegate, create an instance of the delegate and invoke it.
delegate void MyDelegate();
This is our delegate declaration. It returns no value and takes no parameters.
MyDelegate delegate1 = new MyDelegate(MyFunction);
We create an instance of the delegate. When called, the delegate will invoke the static Callback() method.
delegate1 ();
We call the delegate.
Output.
$ ./simple.exe 
Calling MyFunction
Example2:
using System;
 
 
public delegate void NameDelegate(string msg);
 
public class Person 
{
    public string firstName;
    public string secondName;
 
    public Person(string firstName, string secondName)
    { 
        this.firstName = firstName;
        this.secondName = secondName;
    }
 
    public void ShowFirstName(string msg)
    {
        Console.WriteLine(msg + this.firstName);
    }
 
    public void ShowSecondName(string msg)
    {
        Console.WriteLine(msg + this.secondName);
    }
}
 
public class CSharpApp
{
    public static void Main()
    {
        Person per = new Person("Fabius", "Maximus");       
 
        NameDelegate nDelegate = new NameDelegate(per.ShowFirstName);
        nDelegate("Call 1: ");
 
        nDelegate = new NameDelegate(per.ShowSecondName);
        nDelegate("Call 2: ");     
    }
}
In the example we have one delegate. This delegate is used to point to two methods of the Person class. The methods are called with the delegate.
public delegate void NameDelegate(string msg);
The delegate is created with a delegate keyword. The delegate signature must match the signature of the method being called with the delegate.
NameDelegate nDelegate = new NameDelegate(per.ShowFirstName);
nDelegate("Call 1: ");
We create an instance of a new delegate, that points to the ShowFirstName() method. Later we call the method via the delegate.
$ ./simpledelegate.exe 
Call 1: Fabius
Call 2: Maximus
Both names are printed via the delegate.

Multicasting of a Delegate

Delegate objects can be composed using the "+" operator. A composed delegate calls the two delegates it was composed from. Only delegates of the same type can be composed. The "-" operator can be used to remove a component delegate from a composed delegate.
Using this useful property of delegates you can create an invocation list of methods that will be called when a delegate is invoked. This is called multicasting of a delegate.
covariance means we can substitute derived type in place of base type. Contravariance means we can substitute base class in place of derived class