多播委托

前面的每个委托只调用一个方法,一个委托可以包含多个方法,这种委托称为多播委托。如果调用多播委托就可以连续调用多个方法。但是委托的签名的返回值必须是void,否则只能够得到委托调用的最后一个方法的结果。看下面代码

// 多播委托
delegate void DoubleOp (double value );

class MathOperations
{
public static void MultiplyByTwo (double value )
{
double result = value * 2 ;
Console . WriteLine ("{0} Multiply by two = {1}" , value , result );
}
public static void Square (double value )
{
double result = value * value ;
Console . WriteLine ("{0} squrared is {1}" , value , result );
}

static void ProccessAndDisplayNumber (DoubleOp action , double valueToProccess )
{
Console . WriteLine ();
Console . WriteLine ("ProccessAndDisplay called with value = {0}" , valueToProccess );
// 委托会调用相应的方法
action (valueToProccess );
}

// 主函数入口
static void Main ()
{
DoubleOp operations = MathOperations . MultiplyByTwo ;
operations += MathOperations . Square ;

ProccessAndDisplayNumber (operations , 2.0 );
ProccessAndDisplayNumber (operations , 6.51 );

Console . ReadKey ();
}
}

从上面代码看到,声明了一个委托 DoubleOp 并为他指定了两个方法,多播委托会分别连续调用两个方法,并完成对应的操作,输出结果。函数 ProccessAndDisplayNumber 中传递的第一个参数是一个委托类型,因为委托类型与对应的方法有相同的参数和返回值,因此实际传输的是方法,这就是委托的灵活性的体现

使用多播委托时要注意,因为委托调用方法链的顺序并没有正式定义,因此应避免编写依赖于的顶顺序调用方法的代码。还有一个很大的问题需要注意,多播委托包含一个逐个调用的委托的集合。如果通过委托调用的一个方法抛出异常,整个迭代就会停止,看下面示例:

public delegate void Demo ();

class Program
{
public static void One ()
{
Console . WriteLine ("One" );
throw new Exception ("Error in One!" );
}
static void Two ()
{
Console . WriteLine ("Two" );
}
static void Three ()
{
Console . WriteLine ("Three" );
}

static void Main ()
{
Demo d = One ;
d += Two ;
d += Three ;

try
{
d ();
}
catch (Exception )
{
Console . WriteLine ("Exception Caught!!!" );
}
Console . ReadKey ();
}
}

运行一下,可以看到,执行到 One() 就结束了,原因在于这个方法抛出了异常,虽然程序捕获了异常,但是委托的迭代也会就此停止。如果想要避免这个问题,就要手动迭代方法类表,使用delegate类定义的GetInvocationList(),他返回一个 delegate对象数组。因此我们把主函数改写为下:

static void Main ()
{
Demo d = One ;
d += Two ;
d += Three ;

// 使用多播委托d的GetInvocationList方法返回广播委托的调用列表
Delegate [] delegates = d . GetInvocationList ();
foreach (Demo d1 in delegates )
{
try
{
d1 ();
}
catch (Exception )
{
Console . WriteLine ("Exception Caught!!!" );
}
}

Console . ReadKey ();
}

可以看到,结果正确。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值