http://blog.sina.com.cn/s/blog_4b989964010008ev.html
6.2.3 多播委托
前面使用的每个委托都只包含一个方法调用。调用委托的次数与调用方法的次数相同。如果要调用多个方法,就需要多次显式调用这个委托。委托也可以包含多个方法。这种委托称为多播委托。如果调用多播委托,就可以按顺序连续调用多个方法。为此,委托的签名就必须返回void(否则,返回值应送到何处?)。实际上,如果编译器发现某个委托返回void,就会自动假定这是一个多播委托。下面的代码取自于SimpleDelegate示例,尽管其语法与以前相同,但实际上它实例化了一个多播委托Operations:
示例一:
//
static void Main()
{
DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo);
operations += new DoubleOp(MathOperations.Square); 在前面的示例中,要存储对两个方法的引用,所以实例化了一个委托数组。而这里只是在一个多播委托中添加两个操作。多播委托可以识别运算符+和+=。还可以扩展上述代码中的最后两行,它们具有相同的效果:
DoubleOp operation1 = new DoubleOp(MathOperations.MultiplyByTwo);
DoubleOp operation2 = new DoubleOp(MathOperations.Square);
DoubleOp operations = operation1 + operation2; }
}
多播委托还识别运算符–和–=,以从委托中删除方法调用。
注意:
根据后面的内容,多播委托是一个派生于System.MulticastDelegate的类,System.Multicast- Delegate又派生于基类System.Delegate。System.MulticastDelegate的其他成员允许把多个方法调用链接在一起,成为一个列表。
为了说明多播委托的用法,下面把SimpleDelegate示例改写为一个新示例MulticastDelegate。现在需要把委托表示为返回void的方法,就应重写MathOperations类中的方法,让它们显示其结果,而不是返回它们:
public static void MultiplyByTwo(double value)
{
double result = value*2;
Console.WriteLine(
"Multiplying by 2: {0} gives {1}", value, result);
}
public static void Square(double value)
{
double result = value*value;
Console.WriteLine("Squaring: {0} gives {1}", value, result);
}
为了适应这个改变,也必须重写ProcessAndDisplayNumber:
static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
Console.WriteLine("\nProcessAndDisplayNumber called with value = " +
valueToProcess);
action(valueToProcess);
}
下面测试多播委托,其代码如下:
DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo);
operations += new DoubleOp(MathOperations.Square);
ProcessAndDisplayNumber(operations, 2.0);
ProcessAndDisplayNumber(operations, 7.94);
ProcessAndDisplayNumber(operations, 1.414);
Console.WriteLine();
现在,每次调用ProcessAndDisplayNumber时,都会显示一个信息,说明它已经被调用。然后,下面的语句会按顺序调用action委托实例中的每个方法:
运行这段代码,得到如下所示的结果:
ProcessAndDisplayNumber called with value = 2
Multiplying by 2: 2 gives 4
Squaring: 2 gives 4
ProcessAndDisplayNumber called with value = 7.94
Multiplying by 2: 7.94 gives 15.88
Squaring: 7.94 gives 63.0436
ProcessAndDisplayNumber called with value = 1.414
Multiplying by 2: 1.414 gives 2.828
Squaring: 1.414 gives 1.999396
如果使用多播委托,就应注意对同一个委托调用方法链的顺序并未正式定义,因此应避免编写依赖于以任意特定顺序调用方法的代码。
示例二:
public partial class Form1 : Form { //1.decalre delegate public delegate void MyDelegate(); private void Method1() { MessageBox.Show(“Method1 Invoked”); } //lock code start private void Method2() { MessageBox.Show(“Method2 Invoked”); } //lock code End private void button1_Click(object sender, EventArgs e) { //2.create delegate referance MyDelegate myptr = null; //3.point the referance to Add function myptr += this.Method1; ////lock code start myptr += this.Method2; ////lock code end //4.invoke the method through delegate object myptr.Invoke(); } public Form1() { InitializeComponent(); } }