Overview Of Delegates

Delegate

"A delegate is similar to a pointer function in C or C++ that holds reference of a method. It allows to encapsulate reference to a method inside a delegate object .The delegate object can be passed to a code which can call the reference method."

You often read such definitions about delegates, this is true but incomplete.The real purpose of a Delegate is to communicate. As 'delegate' is a English language word and the meaning of this word is to represent or communicate between/among communities, classes, etc.

So the delegate are for communication. We use delegate when one class want to communicate with other class. Of course there are several other ways of doing that, but we should adopt the best way to do any thing.

Why we use Delegate

C# does not allow us passing method reference directly as arguments to other methods, rather it provides delegates.

For example, you write a Class (of code). In this Class you wrote a method. A second person working in your team or elsewhere needs this method which you have written in your class. You would provide delegate to that person so that he/she can call this method.

Delegates are especially useful in event driven environment such as Graphical User Interface(GUI) in which you want that code to execute when user clicks the button.

Note: Delegates are classes that encapsulate set of references to method.

There are two types of delegate:

  1. Single Cast Delegate
  2. Multi Cast Delegate

See the detail of both in later section:

Single Cast Delegate

A delegate that contains a single method is known as Single Cast delegate. And it is derived from the class Delegate.

Multi Cast Delegate

A delegate that contains multiple methods are Multi Cast Delegate.

Both Single Cast Delegate and Multi Cast Delegate belong to Namespace System.

Before using delegates the following point must be considered:

"The method header (Parameter & return value) of a delegate and the method whose reference will be within a delegate object must have same method header."

Let us proceed to some practical examples.

There are the following steps involved in using Delegates:

  1. Declaration
  2. Instantiation
  3. Invocation

Example 1: A simple Delegate

  1. using System;  
  2. namespace Simple.Delegate  
  3. {  
  4.     // Step 1:Declaration  
  5.     public delegate void SimpleDelegate();  
  6.     class MyClass  
  7.     {  
  8.         public static void Print()  
  9.         {  
  10.             Console.WriteLine("Delegate was Printed");  
  11.         }  
  12.         public static void Main()  
  13.         {  
  14.             // Step 2:Instantiation  
  15.             SimpleDelegate simpleDelegate = new SimpleDelegate(Print);  
  16.             // Step 3: Invocation  
  17.             simpleDelegate();  
  18.         }  
  19.     }  
  20. }  
Multi Cast Delegate

"A delegate that contains multiple methods are Multi Cast Delegate.".

We use multi cast delegate when there is need of invoking multiple events like we want to print a string and at the same time we want to write this string in the file or that purpose we use multi cast delegate.

Note: These events are invoked in which sequence you called them. For example, there are two events print and read. The order in which read and print would be invoked depends upon the order in which you would call them (events).

Example 1
  1. // Class 1  
  2. class Name  
  3. {  
  4.     public void Print()  
  5.     {  
  6.         Console.WriteLine("My Name is Usman Arshad");  
  7.     }  
  8. }  
  9. //Class 2  
  10. class Country  
  11. {  
  12.     public void Print()  
  13.     {  
  14.         Console.WriteLine("I am from Pakistan");  
  15.     }  
  16. }  
  17. //Main Class  
  18. namespace  
  19. {  
  20.     public delegate void Multicastdelegate();  
  21.     class Program  
  22.     {  
  23.         Name obj = new Name();  
  24.         Country obj1 = new Country();  
  25.         Multicastdelegate delegate = new Multicastdelegate(obj.Print); //Reference of the print method of class Name  
  26.         delegate = delegate + new Multicastdelegate(obj1.Print); //Just use '+' sign to add more methods  
  27.         obj1.Invoke();  
  28.     }  
  29. }  
Decoupling

Delegates also promote decoupling (It is an Object oriented concept, I will write about that later).

For example, you have written a class of Calculator in which you have written the methods of Addition, Subtraction, Multiplication and Division. Another class is using your methods. You add some more methods in your class, in order to use these methods you also need to change your class.

Delegates provides solution to this problem.

Let us go through an example.

This is a calculator class which takes inputs and perform Addition, Subtraction, Multiplication and Division operations and return result.
  1. namespace Delegates  
  2. {  
  3.     delegate int Mathoperation(int num1, int num2); //Delegate declaration  
  4.     class Calculator  
  5.     {  
  6.         public Mathoperation GetOperation(int option)  
  7.             {  
  8.                 Mathoperation mathOperation = null//Currently, delegate object has no reference  
  9.                 if (option == 1)  
  10.                 {  
  11.                     mathOperation = Add;  
  12.                 }  
  13.                 else if (option == 2)  
  14.                 {  
  15.                     mathOperation = Sub;  
  16.                 }  
  17.                 else if (option == 3)  
  18.                 {  
  19.                     mathOperation = Div;  
  20.                 }  
  21.                 else if (option == 4)  
  22.                 {  
  23.                     mathOperation = Mul;  
  24.                 }  
  25.                 else  
  26.                 {  
  27.                     Console.WriteLine("You choose the wrong option");  
  28.                 }  
  29.                 return mathOperation;  
  30.             }  
  31.             //Mathematical Operations  
  32.         private int Add(int num1, int num2)  
  33.         {  
  34.             return num1 + num2;  
  35.         }  
  36.         private int Sub(int num1, int num2)  
  37.         {  
  38.             return num1 - num2;  
  39.         }  
  40.         private int Div(int num1, int num2)  
  41.         {  
  42.             return num1 / num2;  
  43.         }  
  44.         private int Mul(int num1, int num2)  
  45.         {  
  46.             return num1 * num2;  
  47.         }  
  48.     }  
  49. }  
Here's a class which is using the above class methods.
  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         This is a class which is using these methods.  
  6.         Console.WriteLine("Enter the Option");  
  7.         Console.WriteLine("1.Addition");  
  8.         Console.WriteLine("2.Subtraction");  
  9.         Console.WriteLine("3.Division");  
  10.         Console.WriteLine("4.Multiplication");  
  11.         int option = int.Parse(Console.ReadLine());  
  12.         Calculator Cal_obj = new Calculator();  
  13.         int result = Cal_obj.GetOperation(option)  
  14.             .Invoke(10, 20);  
  15.         Console.WriteLine(result);  
  16.     }  
  17. }  
Now whatever changes you made in your Calculator class, It would not affect your Program Class which is using the methods of this class.

This is called decoupling and Object Oriented Method encourages decoupling.