In this post, we will see what Delegates are and how to use them.
First of all, what is a Delegate?
From Microsoft web site:
“A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate”
In a nutshell, when we define a variable as a “Delegate” we can use it in order to run some methods that have the same signature defined in our Delegate.
SINGLECAST DELEGATE
We define a class called “Operations” and we add two methods called “Sum” and “Subtraction”:
internal class Operations
{
public static string Sum (int val1, int val2)
{
return $"The result of {val1} + {val2} is: {val1 + val2}";
}
public static string Subtraction (int val1, int val2)
{
return $"The result of {val1} - {val2} is: {val1 - val2}";
}
}
Now, we will use a Delegate in order to run these two methods:
// Definition of a delegate
public delegate string DelegateOperations(int val1, int val2);
static void Main(string[] args)
{
// set the delegate with the Sum operation
DelegateOperations delOperations = Operations.Sum;
// invoke the delegate
Console.WriteLine(delOperations(5, 6));
// set the delegate with the Subtraction operation
delOperations = Operations.Subtraction;
// invoke the delegate
Console.WriteLine(delOperations(15, 6));
}
If we run the code, this will be the result:
Obviously, we can use a Delegate with a void methods:
// Definition of a delegate
public delegate void DelegatePrintOperations(int val1, int val2);
static void Main(string[] args)
{
// set the delegate with the PrintSum method
DelegatePrintOperations delOperations = Operations2.PrintSum;
// invoke the delegate
delOperations(5, 6);
// set the delegate with the PrintSubtraction method
delOperations = Operations2.PrintSubtraction;
// invoke the delegate
delOperations(15, 6);
}
internal class Operations2
{
public static void PrintSum(int val1, int val2)
{
Console.WriteLine($"The result of {val1} + {val2} is: {val1 + val2}");
}
public static void PrintSubtraction(int val1, int val2)
{
Console.WriteLine($"The result of {val1} - {val2} is: {val1 - val2}");
}
}
and we can use a Delegate with no static methods:
// Definition of a delegate
public delegate void DelegatePrintOperations(int val1, int val2);
static void Main(string[] args)
{
// create an instance of the Operations3 class
var ope3 = new Operations3();
// set the delegate with the PrintSum method
DelegatePrintOperations delOperations = ope3.PrintSum;
// invoke the delegate
delOperations(5, 6);
// set the delegate with the PrintSubtraction method
delOperations = ope3.PrintSubtraction;
// invoke the delegate
delOperations(15, 6);
}
internal class Operations3
{
public void PrintSum(int val1, int val2)
{
Console.WriteLine($"The result of {val1} + {val2} is: {val1 + val2}");
}
public void PrintSubtraction(int val1, int val2)
{
Console.WriteLine($"The result of {val1} - {val2} is: {val1 - val2}");
}
}
If we try to use a method with a different signature, we will have a compile error:
// Definition of a delegate
public delegate void DelegatePrintOperations(int val1, int val2);
static void Main(string[] args)
{
// set delegate with the Sum operations
DelegateOperations delOperations = Operations.Square;
...
...
...
}
internal class Operations
{
public static string Sum (int val1, int val2)
{
return $"The result of {val1} + {val2} is: {val1 + val2}";
}
public static string Subtraction (int val1, int val2)
{
return $"The result of {val1} - {val2} is: {val1 - val2}";
}
public static string Square(int val1)
{
return $"The result of {val1} squared is: {val1*val1}";
}
}
Finally, we can pass a delegate as an input parameter in a method:
// Definition of a delegate
public delegate void DelegatePrintOperations(int val1, int val2);
static void Main(string[] args)
{
// set the delegate with the Sum operation
DelegatePrintOperations delOperations = Operations2.PrintSum;
// call a method passing in input the delegate
PrintResult(delOperations);
// set the delegate with the Sum operation
delOperations = Operations2.PrintSubtraction;
// call a method passing in input the delegate
PrintResult(delOperations);
}
static void PrintResult(DelegatePrintOperations delegateOperations)
{
delegateOperations(15, 6);
}
internal class Operations2
{
public static void PrintSum(int val1, int val2)
{
Console.WriteLine($"The result of {val1} + {val2} is: {val1 + val2}");
}
public static void PrintSubtraction(int val1, int val2)
{
Console.WriteLine($"The result of {val1} - {val2} is: {val1 - val2}");
}
}
MULTICAST DELEGATE
A delegate that points multiple methods, is called a multicast delegate.
The “+” or “+=” operator adds a function to the invocation list, and the “-” and “-=” operator removes it.
Let’s see some examples:
// Definition of a delegate
public delegate void DelegatePrintOperations(int val1, int val2);
static void Main(string[] args)
{
// definition of two delegates
DelegatePrintOperations delOperations = Operations2.PrintSum;
DelegatePrintOperations delOperations2 = Operations2.PrintSubtraction;
// definition of a delegate that will use both the methods
// we can define finalDelOperations in this way too:
// DelegatePrintOperations finalDelOperations = delOperations + delOperations2;
DelegatePrintOperations finalDelOperations = delOperations;
finalDelOperations += delOperations2;
finalDelOperations(10, 5);
}
...
...
...
If we run the code, this will be the result:
Now, we remove a method:
// Definition of a delegate
public delegate void DelegatePrintOperations(int val1, int val2);
static void Main(string[] args)
{
// set delegate with the Sum operation
DelegatePrintOperations delOperations = Operations2.PrintSum;
DelegatePrintOperations delOperations2 = Operations2.PrintSubtraction;
// we can define finalDelOperations in this way too:
// DelegatePrintOperations finalDelOperations = delOperations + delOperations2;
DelegatePrintOperations finalDelOperations = delOperations;
finalDelOperations += delOperations2;
finalDelOperations(10, 5);
// we remove the delOperations (Operations2.PrintSum)
finalDelOperations -= delOperations;
Console.WriteLine();
finalDelOperations(10,5);
}
...
...
...
If we run the code, this will be the result:
ANONYMOUS DELEGATE
We can create a delegate without declaring a method associated with it and our delegate itself contains the method definition:
// Definition of a delegate
public delegate int DelegateAnonymous(int val1);
static void Main(string[] args)
{
DelegateAnonymous objDeleAnonymous = delegate(int val1) { return val1 * val1; };
Console.WriteLine(objDeleAnonymous(5));
objDeleAnonymous = delegate (int val1) { return val1 * val1 * val1; };
Console.WriteLine(objDeleAnonymous(5));
}
If we run the code, this will be the result: