Delegate Uses in C#

Introduction

This article explains a very beautiful feature of C# called delegates. The use of delegate can be very confusing developers, like where and when to use in actual projects.

What delegates are

The definition says a delegate is a reference type variable that holds a reference to a method/function with a specific parameter list and return type. A delegate is nothing but a type that is declared by the delegate keyword and acts as a type-safe function pointer.

Declaring a delegate

  1. public delegate void myTestDel(string Name);  
When you instantiate a delegate, you can associate its instance with any method with a compatible signature and return type.

The Method getname() has the same signature and return type as the delegate.
  1. public static void getName(string name)  
  2. {  
  3.    Console.WriteLine("My Name: " + name);  
  4. }  
  1. myTestDel del = new myTestDel(getName);  
You can invoke the method through the delegate instance or using the invoke method.
  1. del("By Delagete call- Abhishek singh");  
Or:
  1. del.Invoke(" Using Invoke - Abhishek Singh ");  
Delegates are type-safe function pointers, in other words a delegate is an instance of a static method or instance from a class or struct that matches the delegate type that can be assigned to the delegate. If the method signature is changed then the same code will start giving a complier error due to type safety.

You can see in the following screen that the signature was changed from a string to an int code and that has started giving a compiler error.
 
Delegates in C-Sharp 

Delegates are very powerful since they provide a more flexible and dynamic way to call a method. In the example below the complier is unaware of the information of which the method will be called by del. The information will be given at runtime by the delegates instance constructor that is very flexible to use.
  1. myTestDel del = new myTestDel(getName);   
  2. del("By Delagete call-Abhishek singh");   
Sample Code
  1. namespace Delegates  
  2. {  
  3.    public delegate void myTestDel(string Name);  
  4.    class Program  
  5.    {  
  6.       static void Main(string[] args)  
  7.       {  
  8.          // Normal Methos Call  
  9.          getName("By Normal Method call - Abhishek Singh ");  
  10.   
  11.          //Method Call using delegates  
  12.   
  13.          myTestDel del = new myTestDel(getName);  
  14.          del("By Delagete call-Abhishek singh");  
  15.   
  16.          del.Invoke(" Using Invoke - Abhishek Singh ");  
  17.   
  18.          del = new myTestDel(getLocation);  
  19.          del("Mumbai");  
  20.   
  21.          Console.ReadLine();  
  22.       }
      
  23.       public static void getName(string name)  
  24.       {  
  25.          Console.WriteLine("My Name: " + name);  
  26.       }  
  27.   
  28.       public static void getLocation(string location)  
  29.       {  
  30.          Console.WriteLine("My Loc: " + location);  
  31.       }  
  32.    }  
  33. }  
Important Sticky  
  • Delegates allow methods to be passed as parameters.
  • Delegates are type safe function pointer.
  • Delegate instances attach or detach a method at run time making it more dynamic and flexible to use.
  • Delegates can invoke more than one method using the Multicast feature.
  • Delegates are of reference types.

Multicast Delegate

Delegates can be used to assign multiple objects to one delegate instance meaning simply execute multiple methods in sequence meaning the delegate points to more than one function.
A Multicast delegates holds delegates of the same type in the list that, when called, get invoked in sequence.

  1. myTestDel delmultiCast = new myTestDel(getName);  
  2.   
  3. delmultiCast += getLocation;  
  4.   
  5. delmultiCast("Abhi");  
A Delegate instance can be pointed to by multiple methods using the += sign as stated above. Basically it adds the multiple methods to one delegate instance in the invocation list.

Sample Code
  1. namespace Delegates  
  2. {  
  3.     public delegate void myTestDel(string Name);  
  4.     public delegate void TestMutliCast();  
  5.     public delegate int TestMutliCastint();  
  6.   
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             // Normal Methos Call  
  12.             getName("By Normal Method call - Abhishek Singh ");  
  13.   
  14.             //Method Call using delegates  
  15.   
  16.             myTestDel del = new myTestDel(getName);  
  17.             del("By Delagete call-Abhishek singh");  
  18.   
  19.             del.Invoke(" Using Invoke - Abhishek Singh ");  
  20.   
  21.             del = new myTestDel(getLocation);  
  22.             del("Mumbai");  
  23.   
  24.          //   Mutlticast implementation with void return type  
  25.   
  26.             TestMutliCast delmultiCast = new TestMutliCast(Method1);  
  27.             delmultiCast+=Method2;  
  28.             delmultiCast();  
  29.               
  30.             // Mutlticast implementation with void return type  
  31.   
  32.             myTestDel testMulti = new myTestDel(getName);  
  33.             testMulti += getLocation;  
  34.             testMulti("Abhi");  
  35.   
  36.             // Mutlticast implementation with int return type  
  37.   
  38.             TestMutliCastint intMulti = new TestMutliCastint(Method3);  
  39.             intMulti += Method4;  
  40.            int i= intMulti();  
  41.   
  42.            Console.WriteLine("Return Value is " + i);  
  43.   
  44.             Console.ReadLine();  
  45.         }  
  46.   
  47.         public static void Method1()  
  48.         {  
  49.             Console.WriteLine("Delegate 1st method called!!!!");  
  50.         }  
  51.   
  52.         public static void Method2()  
  53.         {  
  54.             Console.WriteLine("Delegate 2nd method called!!!!");  
  55.         }  
  56.   
  57.         public static int Method3()  
  58.         {  
  59.             Console.WriteLine("Delegate 3rd method called!!!!");  
  60.             return 3;  
  61.         }  
  62.   
  63.         public static int Method4()  
  64.         {  
  65.             Console.WriteLine("Delegate 4th method called!!!!");  
  66.             return 4;  
  67.         }  
  68.   
  69.         public static void getName(string name)  
  70.         {  
  71.             Console.WriteLine("My Name: " + name);  
  72.         }  
  73.   
  74.         public static void getLocation(string location)  
  75.         {  
  76.             Console.WriteLine("My Loc: " + location);  
  77.         }  
  78.     }  
  79. }  
Explanation

By the preceding example I am trying to explain the implementation of Multicast delegates. You can see above that I defined three delegates with different signatures and return type. When you are using multi cast delegate with methods that have a void return type the invocation of the delegate would execute the methods added in the sequence. When the return type is not void as above in my case it is int. Methods with Int return types are added to the delegate instance and will be executed as per the addition sequence but the variable that is holding the return type value will have the value return from the method that is executed at the end.

In the above example the int variable will have a value retuned from method4.

Generally a Multicast delegate is used in the observer pattern for publication and subscriber model programming.

Where to use

A Delegate can be used in various ways dependind on the requirements of the project. The following are the lists of areas where a delegate can be used to provide better output and enhance the performance of the application.

  1. Method Invocation (using delegate instance)
  2. Event Handling using delegate
  3. Callback and asynchronous implementation
  4. Multiple method calls using Multicast delegate

Conclusion

A normal delegate or a Multicast delegate is a very powerful feature in C# and it can be used by developers in various scenarios for more flexibility and a better way to improve the performance of the application.