前面使用的委托只包含一个方法调用。调用委托的次数与调用方法的次数相同。如果要调用多个方法,就需要多次显示调用这个委托。其实委托也可以包含多个方法,这种委托就是多播委托。如果调用多路委托,就可以按顺序连续调用多个方法。
多播委托派生于System.MulticastDelegate,它的Combine方法允许把多个方法调用链接在一起,我们可以通过+和+=来向委托添加调用方法,也可以用-和-=删除其中的调用方法。如:
class Program
{
private delegate void DoubleOP(double x);
static void Main(string[] args)
{
DoubleOP operations = MathsOpration.MutiplybyTwo;
operations += MathsOpration.Square;
ProcessAndDisplay(operations, 2.0);
ProcessAndDisplay(operations, 7.9);
ProcessAndDisplay(operations, 1.414);
Console.ReadKey();
}
static void ProcessAndDisplay(DoubleOP action, double value)
{
Console.WriteLine();
Console.WriteLine("ProcessAndDisplayNumber called with value={0}", value);
action(value );
}
}
class MathsOpration
{
public static void MutiplybyTwo(double value)
{
double result = value * 2;
Console.WriteLine ("Mutiplying 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 );
}
}
结果截图:
注意:
1、多播委托中委托的签名必须返回void;否则,就只能得到委托调用的最后一个方法的结果。
2、如果使用多播委托,就应该注意同一个委托调用链的顺序并未正式定义,因此避免编写依赖于以特定顺序调用方法的代码;
3、多播委托包含一个逐个调用的委托集合。如果通过委托调用的一个方法抛出了异常,整个迭代就会停止。
解决方法:手动迭代方法列表
源代码如下,大家有空可以去尝试下:
//弹出异常,终止迭代的代码
public delegate void DemoTrying();
class Program
{
static void Main()
{
DemoTrying d = One;
d += Two;
try
{
d();
}
catch (Exception e)
{
Console.WriteLine(e.Message );
}
Console.ReadKey();
}
static void One()
{
Console.WriteLine("one");
throw new Exception("Error in one");
}
static void Two()
{
Console.WriteLine("two");
}
}
//更改之后的代码
public delegate void DemoTrying();
class Program
{
static void Main()
{
DemoTrying d = One;
d += Two;
Delegate [] delegates=d.GetInvocationList ();
foreach (DemoTrying d1 in delegates)
{
try
{
d1();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Console.ReadKey();
}
static void One()
{
Console.WriteLine("one");
throw new Exception("Error in one");
}
static void Two()
{
Console.WriteLine("two");
}
}
委托的知识是十分重要的,也是十分广泛的。在此提下委托涉及的其他知识,有意向的同学可以去看下:匿名方法,Lambda表达式,返回类型协变和参数类型抗变等等。其中匿名方法,Lambda表达式有助于简化委托的代码量(以人为本哦)