Overview Of Delegate Concept In C#

Let’s see the delegate concept in C# and .NET with the details of information.

A few important points to remember about delegate in C#.NET:

  1. With the help of delegate in C# and .NET, we can achieve function pointer/Callback functionality concept of C++.
  2. Advantage C# and .NET delegate over C++ function pointer is delegate, which includes type safe information.
  3. Type information like a) Number of parameters,

    1. Types of parameters
    2. Calling convention
    3. Return type

  4. Mainly delegate is used in C# and .NET is for two purposes, which are given below.

    1. Callback &
    2. Event Handling

      Let us see:
      When we call any of the functions but when this function doesn’t return anything back to calling function, in such cases it is something like a one-way communication.

      Callback function=>
      When we call a function but when this function returns something back to the calling function in such cases, it is something like a two-way communication; i.e., nothing but a callback function.

  5. Delegate functionality is provided through System. Delegate Namespace.
  6. Actually delegate is a class, which holds the references to the methods or the functions.
  7. There are different kinds of delegates.

    1. Single Cast delegate.
    2. In this type, it has only one method in its invocation list.
    3. Multicast delegates.
    4. In this type, it has one or more than one method/methods in its invocation list.
    5. Again, there are two types of Multicast delegate.
    6. Multicast delegate with void return types.
    7. Multicast delegate with non-void return types.

  8. About delegate method

    1. Delegate method is a method, whose reference is encapsulated in delegate instance.

  9. About delegate instance

    1. It is actually an object of delegate class.

Now, let us start,

First of all, we will look into

  • Single Cast delegate

The code snippet is given below.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. //Sandip Patil Practices  
  7. namespace delegateDemoApp {  
  8.     class demoApp {  
  9.         public delegate int ArithOp(int x, int y);  
  10.         class MathOps {  
  11.             public static int Add(int a, int b) {  
  12.                 return (a + b);  
  13.             }  
  14.             public static int Mul(int a, int b) {  
  15.                 return (a * b);  
  16.             }  
  17.         }  
  18.         static void Main(string[] args) {  
  19.             ArithOp Op1 = new ArithOp(MathOps.Add);  
  20.             ArithOp Op2 = new ArithOp(MathOps.Mul);  
  21.             int k1 = Op1(10, 20);  
  22.             int k2 = Op2(10, 20);  
  23.             Console.WriteLine("Addition:" + k1);  
  24.             Console.WriteLine("Multiplication:" + k2);  
  25.             Console.Read();  
  26.         }  
  27.     }  
  28. }  
Explanation

In above program,
  1. Declaration of delegate is given in the code line given below.
    1. public delegate int ArithOp(int x, int y);  
  2. A delegate method is given below since it matches the signature of delegate. 

    The code line given below demonstrates how Add is a delegate method.
    1. public static int Add(int a, int b)  
    2. {  
    3.    return (a + b);  
    4. }  
  3. Instantiation of delegate

    The code line given below demonstrates it.
    1. ArithOp Op1 = new ArithOp(MathOps.Add);  
    Now, here MathOps.Add is a delegate method, since its reference is encapsulated in delegate instance Op1.

  4. Invocation of delegate method

    The code line given below demonstrates it.

    Invocation of MathOps.Add as a delegate method.
    1. int k1 = Op1(10, 20);  
    It returns an integer value,

    Output of the above program is given below.

    Addition 30
    Multiplication 200

Now, let us see,

How to create an array of delegate instances

The code snippet is given below for it.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. namespace ArrayOfdelegateInstances {  
  7.     class demoApp {  
  8.         public delegate int ArithOp(int x, int y);  
  9.         class MathOps {  
  10.             public static int Add(int a, int b) {  
  11.                 return (a + b);  
  12.             }  
  13.             public static int Mul(int a, int b) {  
  14.                 return (a * b);  
  15.             }  
  16.             public static void ProcessMethod(ArithOp operation, int c, int d) {  
  17.                 int k11 = operation(c, d);  
  18.                 Console.WriteLine("Addition " + k11);  
  19.             }  
  20.         }  
  21.         static void Main(string[] args) {  
  22.             ArithOp[] operation = {  
  23.                 new ArithOp(MathOps.Add),  
  24.                 new ArithOp(MathOps.Mul)  
  25.             };  
  26.             MathOps.ProcessMethod(operation[0], 22, 33);  
  27.             Console.Read();  
  28.         }  
  29.     }  
  30. }  
Explanation

In the program given above,
  1. The line given below indicates how to create an array of delegate instances.
    1. ArithOp[] operation = { new ArithOp(MathOps.Add), new ArithOp(MathOps.Mul) };  
  2. Now, let us try to understand, how to invoke delegate method from this array.

    The code line given below indicates how to invoke delegate method from this array.
    1. MathOps.ProcessMethod(operation[0], 22, 33);  
    Here, it invokes Add method.

    Observe, the output of the program given above is given below.

    Addition 55

    Now, we will look into

    1. Multicast delegates
      In this, first of all we will see Multicast delegate with void return types. The code snippet is given below for it.
      1. using System;  
      2. using System.Collections.Generic;  
      3. using System.Linq;  
      4. using System.Text;  
      5. using System.Threading.Tasks;  
      6. //sandip patil DemoApp  
      7. namespace voidMulticastDelegate {  
      8.     class MyProgVoidMulticastDelegate {  
      9.         public delegate void Mdelegate();  
      10.         class MathOps {  
      11.             public static void M1() {  
      12.                 Console.WriteLine("M1");  
      13.             }  
      14.             public static void M2() {  
      15.                 Console.WriteLine("M2");  
      16.             }  
      17.         }  
      18.         static void Main(string[] args) {  
      19.             Mdelegate k1 = new Mdelegate(MathOps.M1);  
      20.             Mdelegate k2 = new Mdelegate(MathOps.M2);  
      21.             Mdelegate k3 = k1 + k2;  
      22.             k3();  
      23.             Console.Read();  
      24.         }  
      25.     }  
      26. }  

Explanation

In the program given above.

  1. M1 and M2 are both delegate methods with void return type.
  2. The code lines given below indicates that M1 and M2 are encapsulated into k1 and k2.
    1. Mdelegate k1 = new Mdelegate(MathOps.M1);  
    2. Mdelegate k2 = new Mdelegate(MathOps.M2);  
  3. The line given below indicates that k3 is delegate instance with M1 and M2 is encapsulated into it.
    1. Mdelegate k3 = k1 + k2;  
  4. Now, let’s see how to invoke multicast delegate.

    The code line given below demonstrates it.
    1. k3();  
    Here, it invokes both M1 and M2 Method at a time in a single call i.e. k3 has more than one method in its invocation list.

    Observe the output of the program given above is shown below.

    M1
    M2

Let us see Multicast delegate with Non-void return types.

The code snippet is given below for it.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. //sandip patil DemoApp  
  7. namespace nonVoidMulticast {  
  8.     class Program {  
  9.         public delegate int Fun < T > ();  
  10.         class MathsOp {  
  11.             public static int M1() {  
  12.                 Console.WriteLine("M1");  
  13.                 return 1;  
  14.             }  
  15.             public static int M2() {  
  16.                 Console.WriteLine("M2");  
  17.                 return 2;  
  18.             }  
  19.         }  
  20.         static void Main(string[] args) {  
  21.             Fun < int > d1 = MathsOp.M1;  
  22.             Fun < int > d2 = MathsOp.M2;  
  23.             Fun < int > d = d1 + d2;  
  24.             foreach(Fun < int > i in d.GetInvocationList()) {  
  25.                 int r = i();  
  26.                 Console.WriteLine("" + r);  
  27.             }  
  28.             Console.Read();  
  29.         }  
  30.     }  
  31. }  
Explanation

In the program given above.
  1. Observe the delegate declaration for non-void return type and the code line given below demonstrates it.
    1. public delegate int Fun<T>();  
    Function template is used here.

  2. Observe how delegate is instantiated and the code line given below demonstrates it.
    1. Fun<int> d1 = MathsOp.M1;  
  3. Now, observe the code given below.
    1. Fun<int> d = d1 + d2;  
    Here both methods are encapsulated

  4. Important point is =>in order to invoke Multicast delegate with non-void return type, we need to use GetInvocationList() Method.

    The code snippet given below demonstrates it.
    1. foreach (Fun<int> i in d.GetInvocationList())  
    2. {  
    3.    int r = i();  
    4.    Console.WriteLine("" + r);  
    5. }  
    Observe the output of the program given above is shown below.

    M1
    1
    M2
    2