Previous Page Next Page
Delegates in the .Net Framework
Although C# presents delegates as a keyword and as a first class language construct, in .Net delegates are present as a reference type, and all delegates inherit from the System.Delegate type. Hence, technically, our prior definition that said 'a delegate is a reference to a method' is not quite appropriate. A delegate is a reference type derived from System.Delegate and its instances can be used to call methods with matching signatures. Another important thing to note here is that since defining a delegate means creating a new sub-type of System.Delegate, the delegates can not be defined within a method (which is also true for ordinary types). This is the reason why we have defined the delegate MyDelegate outside the Main() method in the example code of this lesson.
class Test
{
delegate int MyDelegate(int p, int q);
static void Main()
{
MyDelegate arithMethod = null;
...
}
}
Passing delegates to methods
Just like a reference to an object can be passed to other objects, the delegate reference of one method can be passed to another method. For example, lets make a method called 'PerformArithOperation()', which takes two integers and a delegate reference of type MyDelegate, and calls the encapsulated method using the two integers.
static void PerformArithOperation(int a, int b, MyDelegate arithOperation)
{
int r = arithOperation(a, b);
Console.WriteLine("\nThe result of arithmetic operation on 3
and 4 is: {0}", r);
}
Now in the Main() method, we will call this method as
PerformArithOperation(3, 4, arithMethod);
Hence, the task of collecting and printing the result has been delegated (or transferred) to the PerformArithOperation() method. The complete source code of the program is shown below.
using System;
namespace CSharpSchool
{
class Test
{
delegate int MyDelegate(int p, int q);
static void Main()
{
MyDelegate arithMethod = null;
Console.WriteLine("Which arithmetic operation you
like to perform on 3 and 4?");
Console.WriteLine("Press + for Add ");
Console.WriteLine("Press - for Subtract ");
Console.Write("Press m for Maximum Number ");
char choice = (char) Console.Read();
switch(choice)
{
case '+':
arithMethod = new MyDelegate(Add);
break;
case '-':
arithMethod = new MyDelegate(Subtract);
break;
case 'm':
arithMethod = new MyDelegate(Max);
break;
}
PerformArithOperation(3, 4, arithMethod);
}
static void PerformArithOperation(int a, int b, MyDelegate
arithOperation)
{
int r = arithOperation(a, b);
Console.WriteLine("\nThe result of arithmetic
operation on 3 and 4 is: {0}", r);
}
static int Add(int a, int b)
{
return a + b;
}
static int Subtract(int a, int b)
{
return a-b;
}
static int Max(int c, int d)
{
if(c>d)
return c;
else
return d;
}
}
}
Multicast Delegates
A special feature of delegates is that a single delegate can encapsulate more than one method of a matching signature. These kind of delegates are called 'Multicast Delegates'. Internally, multicast delegates are sub-types of System.MulticastDelegate, which itself is a subclass of System.Delegate. The most important point to remember about multicast delegates is that "The return type of a multicast delegate type must be void". The reason for this limitation is that a multicast delegate may have multiple methods in its invocation list. Since a single delegate (or method) invocation can return only a single value, a multicast delegate type must have the void return type.
Implementing a Multicast Delegate
A multicast delegate is defined in exactly the same way as a simple delegates, with the exception that the return type of a multicast delegate is strictly void.
delegate void MyMulticastDelegate(int p, int q);
The different methods are added to multicast delegate's invocation list by using '+=' assignment operator, like this:
MyMulticastDelegate arithMethod = null;
arithMethod = new MyMulticastDelegate(Add);
arithMethod += new MyMulticastDelegate(Subtract);
arithMethod += new MyMulticastDelegate(Max);
The invocation of a multicast delegate is again similar to that of normal delegates and methods except that it in turn calls all the encapsulated methods.
arithMethod(3, 4);
The complete source code of this example is shown below.
using System;
namespace CSharpSchool
{
class Test
{
delegate void MyMulticastDelegate(int p, int q);
static void Main()
{
MyMulticastDelegate arithMethod = null;
arithMethod = new MyDelegate(Add);
arithMethod += new MyDelegate(Subtract);
arithMethod += new MyDelegate(Max);
arithMethod(3, 4);
}
static void Add(int a, int b)
{
Console.WriteLine("The sum of 3 and 4 is: {0}", a+b);
}
static void Subtract(int a, int b)
{
Console.WriteLine("The difference of 3 and 4 is: {0}", a-b);
}
static void Max(int c, int d)
{
if(c>d)
Console.WriteLine("The Maximum of 3 and 4 is: {0}", c);
else
Console.WriteLine("The Maximum of 3 and 4 is: {0}", d);
}
}
}
Note that we have changed the Add(), Subtract() and Max() methods so that they have a void return type and print out the result of their respective operations within the body of the method. The output of the program is:
The sum of 3 and 4 is: 7
The difference of 3 and 4 is: -1
The Maximum of 3 and 4 is: 4
Press any key to continue
Note that the single delegate invocation has invoked all of the encapsulated methods. This concept is used in the event handling mechanism of .Net, described later in the lesson, where each event handler method is called (when the event is fired) through the multicast delegate.
Previous Page Next Page