Simple, Multicast And Generic Delegates In Their Simplest Form For Beginners

Introduction

This blog will help beginners understand the concept of delegates, their types, and their actual implementation, in the simplest possible way.

What are Delegates?

Delegates are the pointers to function. It defines what a function looks like.

Types of Delegate

  • Simple Delegate
  • Multicast Delegate
  • Generic Delegate
    • Func
    • Action
    • Predicate

Simple Delegate

public delegate int MyDeleate(int a, int b);

We can create a delegate using the keyword delegate. The above delegate can hold the reference of any method which has two int parameters and returns int.

Let’s do some code!

  1. public class Math  
  2. {  
  3.     public int Add(int a, int b)   
  4.    {  
  5.         return (a + b);  
  6.     }  
  7. }  
  8. static void Main(string[] args) {  
  9.     Math m = new Math();  
  10.     //Create object of Delegate. Provide method name as parameter  
  11.     MyDeleate mydelegate = new MyDeleate(m.Add);  
  12.     //Call Delegate  
  13.     var result = mydelegate(10, 20);  
  14.     Console.WriteLine(result);  
  15. }  
To call the delegate, we need to first create an object of delegate, and then pass the method name as parameter whose reference delegate should hold.

We can, then, call the delegate similarly as we call any method.

Multicast Delegate

Multicast Delegates can point to multiple methods. Once delegate objects are created, we can play with them.

Let’s take an example.
  1. public delegate void FunDelegate(); //Delegate  
  2. static void Main(string[] args)   
  3. {  
  4.     Fun f = new Fun();  
  5.     FunDelegate fun1 = new FunDelegate(f.PrintHi);  
  6.     FunDelegate fun2 = new FunDelegate(f.PrintBye);  
  7.     FunDelegate fun3;  
  8.     FunDelegate fun4;  
  9.     FunDelegate fun5;  
  10.     fun3 = fun1 + fun2; //Multicast Delegate  
  11.     fun4 = fun1 - fun2; //Multicast Delegate  
  12.     fun5 = fun2 - fun1; //Multicast Delegate  
  13.     Console.WriteLine("----- Calling fun1----");  
  14.     fun1();  
  15.     Console.WriteLine("----- Calling fun2----");  
  16.     fun2();  
  17.     Console.WriteLine("----- Calling fun3----");  
  18.     fun3();  
  19.     Console.WriteLine("----- Calling fun4----");  
  20.     fun4();  
  21.     Console.WriteLine("----- Calling fun5----");  
  22.     fun5();  
  23.     Console.ReadKey();  
  24. }  
  25. class Fun  
  26. {  
  27.     public void PrintHi() {  
  28.         Console.WriteLine("Hi");  
  29.     }  
  30.     public void PrintBye() {  
  31.         Console.WriteLine("Bye");  
  32.     }  
  33. }  
The output of the above code would be:
 
 
Generic Delegate

Generic Delegates can work with any type of parameter.
  1. class Program  
  2. {  
  3.     public delegate double GenericDelegate < T1, T2 > (T1 a, T2 b);  
  4.     static void Main(string[] args)  
  5.     {  
  6.         Math m = new Math();  
  7.         GenericDelegate < intint > del1 = new GenericDelegate < intint > (m.Add);  
  8.         GenericDelegate < doubledouble > del2 = new GenericDelegate < doubledouble > (m.Mult);  
  9.         var result1 = del1(10, 20);  
  10.         var result2 = del2(20.4, 70.5);  
  11.         Console.WriteLine(result1);  
  12.         Console.WriteLine(result2);  
  13.         Console.ReadKey();  
  14.     }  
  15. }  
  16. class Math  
  17. {  
  18.     public double Add(int a, int b) {  
  19.         return a + b;  
  20.     }  
  21.     public double Mult(double a, double b) {  
  22.         return a * b;  
  23.     }  
  24.     public void PrintAdd(int a, int b) {  
  25.         Console.WriteLine(a + b);  
  26.     }  
  27.     public bool IsInteger(string a) {  
  28.         int outParam;  
  29.         return int.TryParse(a, out outParam);  
  30.     }  
To reduce the coding efforts of writing Generic Delegates, C# provides some in-built Generic Delegates, named as: 
  1. Func: Takes up to 16 input parameters and has to return some value.
  2. Action: Takes up to 16 input parameters and does not return anything (returns void).
  3. Predicate: Takes 1 input parameter and returns boolean value.

Func

  1. Math m = new Math();  
  2. // Delegate With Method  
  3. Func<intintdouble> func1 = m.Add;  
  4.   
  5. //Annonomyous Method  
  6. Func<intintdouble> func2 = delegate (int a, int b) { return a + b; };   
  7.   
  8. //Lamda Expression   
  9. Func<intintdouble> func3 = (int a, int b) => { return a + b; };  
  10. double result1 = func1(10, 20);  
Action
  1. Math m = new Math()  
  2. // Delegate with Method  
  3. Action<intint> action1 = m.PrintAdd;  
  4.   
  5. //Annonomyous Method  
  6. Action<intint> action2 = delegate (int a, int b) { Console.WriteLine(a + b); };   
  7.   
  8. //Lamda Expression  
  9. Action<intint> action3 = (int a, int b) => { Console.WriteLine(a + b); };  
  10.   
  11. action1(10,20);  
Predicate
  1. Math m = new Math();  
  2.   
  3. //Delegate with Method  
  4. Predicate<string> predicate1 = m.IsInteger;  
  5.   
  6. //Annonomyous Method  
  7. Predicate<string> predicate2 = delegate (string a)   
  8. {   
  9. int outParam;   
  10. return int.TryParse(a, out outParam);   
  11. };  
  12.   
  13. //Lamda Expression  
  14. Predicate<string> predicate3 = (string a) =>   
  15. {   
  16. int outParam;   
  17. return int.TryParse(a, out outParam);  
  18. };  
  19. bool result = predicate1("123");