Delegate Basics in C#


Delegates are reference types that take a method as parameter and once the delegate is invoked the method is called. Once we declare a delegate we need to provide the parameters that our function is expecting and also provide the return type of the function as shown below.

public delegate void MyDelegate(int number);

The preceding delegate expects a method that takes a single integer parameter and returns void.

What the CLR does to delegates

Suppose we declare a delegate as shown in the code listing below:

  1. public class DelegareUsage  
  2. {  
  3.    public delegate void MyDelegate(int number);  
  4. }  
What the CLR does is it creates a class in the IL code as shown in the figure below.


As we can see in the preceding figure a sealed class is created in the IL after the compilation of the code. As we can see the delegate class contains by default three functions, in other words BeginInvoke, EndInvoke, Invoke.

How a Delegate is Initilized

We can create an instance of the delegate as shown below:
  1. MyDelegate del = new MyDelegate(Display);  
Or alternatively we can also initialize a delegate as follows by directly assigning the method to the delegate instance.
  1. MyDelegate del = Display;  
In both of the preceding cases a variable of type MyDelegate is created that would be further used to call the method synchronously or asynchronously.

Now why did I say synchronously or asynchronously? As described earlier, every time a delegate is declared, two types of methods are created that can be used to call the referenced method. They are:

1. Invoke: This is the default way by which a method is being called. Suppose I have a method as shown below:
  1. public static void Display(int display)  
  2. {  
  3.    Console.WriteLine(display);  
  4. }  
And I want to call this method synchronously I can do it in the following ways.

del.Invoke(10); or

2. BeginInvoke: Now suppose I have a function that takes time to execute and I want to return as soon as the function is called. This I can do as in the following.
  1. del.BeginInvoke(10,nullnull)  
  2. public static void TimeTakingFunction(int display)  
  3. {  
  4.    Thread.Sleep(5000);  
  5.    Console.WriteLine(display);  
  6. }  
This will return control to the caller as soon as the preceding statement is executed and it will not wait for the function to return or end the execution.

MultiCast Delegate

The hierarachy of the inheritance for the delegates is that the user defined delegate is derived from a multicast delegate. Each delegate contains an invocation list, in other words we can attach any number of functions to the delegates. The functions can be attached to the invocation list using the operator +=. The functions in the multicast delegates are called in the order they are added. We usually expect a multicast delegate to return void as if we have multiple functions that return anything but void in that case the value returned from the last called function is retained in the variable.
  1. class Program  
  2. {  
  3.    public delegate void MyDelegate(int number);  
  4.    static void Main(string[] args)  
  5.    {  
  6.       MyDelegate del = TimeTakingFunction;  
  7.       del += AnotherTimeTakinFunction;  
  8.       del.Invoke(10);  
  9.       Console.WriteLine("In the main");  
  10.       Console.ReadKey();  
  11.    }  
  12.    public static void Display(int display)  
  13.    {  
  14.       Console.WriteLine(display);  
  15.       Console.ReadKey();  
  16.    }  
  17.    public static void TimeTakingFunction(int display)  
  18.    {  
  19.       Thread.Sleep(5000);  
  20.       Console.WriteLine("First time taking function " + display);  
  21.    }  
  22.    public static void AnotherTimeTakinFunction(int display)  
  23.    {  
  24.       Thread.Sleep(5000);  
  25.       Console.WriteLine("Second time taking function " + display);  
  26.    }  
  27. }  
This was all about the basics of delegates. Please provide your comments about the article.