Êíèãà: C# 2008 Programmer
Delegates Chaining (Multicast Delegates)
Delegates Chaining (Multicast Delegates)
In the previous section, a delegate pointed to a single function. In fact, you can make a delegate point to multiple functions. This is known as delegates chaining. Delegates that point to multiple functions are known as multicast delegates.
Consider the following example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Delegates {
class Program {
delegate void MethodsDelegate();
static void Main(string[] args) {
MethodsDelegate methods = Method1;
methods += Method2;
methods += Method3;
//---call the delegated method(s)---
methods();
Console.ReadLine();
}
static private void Method1() {
Console.WriteLine("Method 1");
}
static private void Method2() {
Console.WriteLine("Method 2");
}
static private void Method3() {
Console.WriteLine("Method 3");
}
}
}
This program three methods: Method1()
, Method2()
, and Method3()
. The methods delegate is first assigned to point to Method1()
. The next two statements add Method2()
and Method3()
to the delegate by using the +=
operator:
MethodsDelegate methods = Method1;
methods += Method2;
methods += Method3;
When the methods delegate variable is called, the following output results:
Method 1
Method 2
Method 3
The output shows that the three methods are called in succession, in the order they were added.
What happens when your methods each return a value and you call them using a multicast delegate? Here's an example in which the three methods each return an integer value:
class Program {
delegate int MethodsDelegate(ref int num1, ref int num2);
static void Main(string[] args) {
int num1 = 0, num2 = 0;
MethodsDelegate methods = Method1;
methods += Method2;
methods += Method3;
//---call the delegated method(s)---
Console.WriteLine(methods(ref num1, ref num2));
Console.WriteLine("num1: {0} num2: {1}", num1, num2);
Console.ReadLine();
}
static private int Method1(ref int num1, ref int num2) {
Console.WriteLine("Method 1");
num1 = 1;
num2 = 1;
return 1;
}
static private int Method2(ref int num1, ref int num2) {
Console.WriteLine("Method 2");
num1 = 2;
num2 = 2;
return 2;
}
static private int Method3(ref int num1, ref int num2) {
Console.WriteLine("Method 3");
num1 = 3;
num2 = 3;
return 3;
}
}
When the methods delegate is called, Method1()
, Method2()
, and Method3()
are called in succession. However, only the last method (Method3()
) returns a value back to the Main()
function, as the output shows:
Method 1
Method 2
Method 3
3
num1: 3 num2: 3
If one of the methods pointed to by a delegate causes an exception, no results are returned.
The following modifications to the preceding program shows that Method2()
throws an exception and is caught by the try-catch
block:
class Program {
delegate int MethodsDelegate(ref int num1, ref int num2);
static void Main(string[] args) {
int num1 = 0, num2 = 0;
MethodsDelegate methods = Method1;
methods += Method2;
methods += Method3;
try {
//---call the delegated method(s)---
Console.WriteLine(methods(ref num1, ref num2));
Console.WriteLine("num1: {0} num2: {1}", num1, num2);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.WriteLine("num1: {0} num2: {1}", num1, num2);
Console.ReadLine();
}
static private int Method1(ref int num1, ref int num2) {
Console.WriteLine("Method 1");
num1 = 1;
num2 = 1;
return l;
}
static private int Method2(ref int num1, ref int num2) {
throw new Exception();
Console.WriteLine("Method 2");
num1 = 2;
num2 = 2;
return 2;
}
static private int Method3(ref int num1, ref int num2) {
Console.WriteLine("Method 3");
num1 = 3;
num2 = 3;
return 3;
}
}
The following output shows that num1
and num2
retain the values set by the last method that was successfully invoked by the delegate:
Method 1
Exception of type 'System.Exception' was thrown.
num1: 1 num2: 1
Just as you use the +=
operator to add a method to a delegate, you use the -=
operator to remove a method from a delegate:
static void Main(string[] args) {
int num1 = 0, num2 = 0;
MethodsDelegate methods = Method1;
methods += Method2;
methods += Method3;
//...
//...
//---removes Method3---
methods -= Method3;