Let’s see the delegate concept in C# and .NET with the details of the 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 the function pointer/Callback functionality concept of C++.
2. Advantage C# and .NET delegate over C++ function pointer is a delegate, which includes type-safe information.
3. Type information like a) Number of parameters.
- Types of parameters
- Calling convention
- Return type
4. Mainly delegate is used in C# and .NET for two purposes, which are given below.
- Callback &
- Event Handling
a. Let us see: When we call any of the functions but when this function doesn’t return anything back to the calling function, in such cases it is something like a one-way communication.
b. 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 the 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.
- Single Cast delegate.
- In this type, it has only one method in its invocation list.
- Multicast delegates.
- In this type, it has one or more than one method/method in its invocation list.
- Again, there are two types of Multicast delegates.
- Multicast delegate with void return types.
- Multicast delegate with non-void return types.
8. About the delegate method: The delegate method is a method, whose reference is encapsulated in the delegate instance.
9. About delegate instance: It is actually an object of the delegate class.
Now, let us start.
First of all, we will look into it.
Single Cast delegate
The code snippet is given below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// Sandip Patil Practices
namespace delegateDemoApp
{
class DemoApp
{
public delegate int ArithOp(int x, int y);
class MathOps
{
public static int Add(int a, int b)
{
return a + b;
}
public static int Mul(int a, int b)
{
return a * b;
}
}
static void Main(string[] args)
{
ArithOp Op1 = new ArithOp(MathOps.Add);
ArithOp Op2 = new ArithOp(MathOps.Mul);
int k1 = Op1(10, 20);
int k2 = Op2(10, 20);
Console.WriteLine("Addition: " + k1);
Console.WriteLine("Multiplication: " + k2);
Console.Read();
}
}
}
Explanation
In the above program.
- The declaration of delegate is given in the code line given below.
public delegate int ArithOp(int x, int y);
- A delegate method is given below since it matches the signature of the delegate.
- The code line given below demonstrates how Add is a delegate method.
public static int Add(int a, int b)
{
return (a + b);
}
- Instantiation of delegate
- The code line given below demonstrates it.
ArithOp Op1 = new ArithOp(MathOps.Add);
- Now, here MathOps.Add is a delegate method since its reference is encapsulated in delegate instance Op1.
- Invocation of the delegate method
- The code line given below demonstrates it.
- Invocation of MathOps.Add as a delegate method.
int k1 = Op1(10, 20);
- It returns an integer value.
The 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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ArrayOfDelegateInstances
{
class DemoApp
{
public delegate int ArithOp(int x, int y);
class MathOps
{
public static int Add(int a, int b)
{
return a + b;
}
public static int Mul(int a, int b)
{
return a * b;
}
public static void ProcessMethod(ArithOp operation, int c, int d)
{
int result = operation(c, d);
Console.WriteLine("Result: " + result);
}
}
static void Main(string[] args)
{
ArithOp[] operations =
{
new ArithOp(MathOps.Add),
new ArithOp(MathOps.Mul)
};
MathOps.ProcessMethod(operations[0], 22, 33);
Console.Read();
}
}
}
Explanation
In the program given above.
- The line given below indicates how to create an array of delegate instances.
ArithOp[] operation = {
new ArithOp(MathOps.Add),
new ArithOp(MathOps.Mul)
};
- Now, let us try to understand, how to invoke the delegate method from this array.
- The code line given below indicates how to invoke the delegate method from this array.
MathOps.ProcessMethod(operation[0], 22, 33);
Here, it invokes the Add method.
Observe, the output of the program given above is given below.
Addition 55M
Now, we will look into it.
Multicast delegates
In this, first of all, we will see Multicast delegate with void return types. The code snippet is given below for it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// Sandip Patil DemoApp
namespace VoidMulticastDelegate
{
class MyProgVoidMulticastDelegate
{
public delegate void Mdelegate();
class MathOps
{
public static void M1()
{
Console.WriteLine("M1");
}
public static void M2()
{
Console.WriteLine("M2");
}
}
static void Main(string[] args)
{
Mdelegate k1 = new Mdelegate(MathOps.M1);
Mdelegate k2 = new Mdelegate(MathOps.M2);
Mdelegate k3 = k1 + k2;
k3();
Console.Read();
}
}
}
Explanation
In the program given above.
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.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// sandip patil DemoApp
namespace nonVoidMulticast
{
class Program
{
public delegate int Fun<T>();
class MathsOp
{
public static int M1()
{
Console.WriteLine("M1");
return 1;
}
public static int M2()
{
Console.WriteLine("M2");
return 2;
}
}
static void Main(string[] args)
{
Fun<int> d1 = MathsOp.M1;
Fun<int> d2 = MathsOp.M2;
Fun<int> d = d1 + d2;
foreach (Fun<int> i in d.GetInvocationList())
{
int r = i();
Console.WriteLine("" + r);
}
Console.Read();
}
}
}
Explanation
In the program given above.
- Observe the delegate declaration for non-void return type and the code line given below demonstrates it.
public delegate int Fun<T>();
- A function template is used here.
- Observe how delegate is instantiated and the code line given below demonstrates it.
Fun<int> d1 = MathsOp.M1;
- Now, observe the code given below.
Fun<int> d = d1 + d2;
- Here both methods are encapsulated.
- Important point is =>in order to invoke Multicast delegate with non-void return type, we need to use the GetInvocationList() Method.
- The code snippet given below demonstrates it.
foreach (Fun<int> i in d.GetInvocationList())
{
int r = i();
Console.WriteLine("" + r);
}
Observe the output of the program given above is shown below.
M1
1
M2
2