: 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;


: 1.393. /Cache: 3 / 0