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
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!
- public class Math
- {
- public int Add(int a, int b)
- {
- return (a + b);
- }
- }
- static void Main(string[] args) {
- Math m = new Math();
-
- MyDeleate mydelegate = new MyDeleate(m.Add);
-
- var result = mydelegate(10, 20);
- Console.WriteLine(result);
- }
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.
- public delegate void FunDelegate();
- static void Main(string[] args)
- {
- Fun f = new Fun();
- FunDelegate fun1 = new FunDelegate(f.PrintHi);
- FunDelegate fun2 = new FunDelegate(f.PrintBye);
- FunDelegate fun3;
- FunDelegate fun4;
- FunDelegate fun5;
- fun3 = fun1 + fun2;
- fun4 = fun1 - fun2;
- fun5 = fun2 - fun1;
- Console.WriteLine("----- Calling fun1----");
- fun1();
- Console.WriteLine("----- Calling fun2----");
- fun2();
- Console.WriteLine("----- Calling fun3----");
- fun3();
- Console.WriteLine("----- Calling fun4----");
- fun4();
- Console.WriteLine("----- Calling fun5----");
- fun5();
- Console.ReadKey();
- }
- class Fun
- {
- public void PrintHi() {
- Console.WriteLine("Hi");
- }
- public void PrintBye() {
- Console.WriteLine("Bye");
- }
- }
The output of the above code would be:
Generic Delegate
Generic Delegates can work with any type of parameter.
- class Program
- {
- public delegate double GenericDelegate < T1, T2 > (T1 a, T2 b);
- static void Main(string[] args)
- {
- Math m = new Math();
- GenericDelegate < int, int > del1 = new GenericDelegate < int, int > (m.Add);
- GenericDelegate < double, double > del2 = new GenericDelegate < double, double > (m.Mult);
- var result1 = del1(10, 20);
- var result2 = del2(20.4, 70.5);
- Console.WriteLine(result1);
- Console.WriteLine(result2);
- Console.ReadKey();
- }
- }
- class Math
- {
- public double Add(int a, int b) {
- return a + b;
- }
- public double Mult(double a, double b) {
- return a * b;
- }
- public void PrintAdd(int a, int b) {
- Console.WriteLine(a + b);
- }
- public bool IsInteger(string a) {
- int outParam;
- return int.TryParse(a, out outParam);
- }
To reduce the coding efforts of writing Generic Delegates, C# provides some in-built Generic Delegates, named as: - Func: Takes up to 16 input parameters and has to return some value.
- Action: Takes up to 16 input parameters and does not return anything (returns void).
- Predicate: Takes 1 input parameter and returns boolean value.
Func
- Math m = new Math();
-
- Func<int, int, double> func1 = m.Add;
-
-
- Func<int, int, double> func2 = delegate (int a, int b) { return a + b; };
-
-
- Func<int, int, double> func3 = (int a, int b) => { return a + b; };
- double result1 = func1(10, 20);
Action
- Math m = new Math()
-
- Action<int, int> action1 = m.PrintAdd;
-
-
- Action<int, int> action2 = delegate (int a, int b) { Console.WriteLine(a + b); };
-
-
- Action<int, int> action3 = (int a, int b) => { Console.WriteLine(a + b); };
-
- action1(10,20);
Predicate
- Math m = new Math();
-
-
- Predicate<string> predicate1 = m.IsInteger;
-
-
- Predicate<string> predicate2 = delegate (string a)
- {
- int outParam;
- return int.TryParse(a, out outParam);
- };
-
-
- Predicate<string> predicate3 = (string a) =>
- {
- int outParam;
- return int.TryParse(a, out outParam);
- };
- bool result = predicate1("123");