复制委托链上的委托对象

  CLR默认的委托链调用处理在大多数情况下已经很好用了。但考虑一下以下的情况:

  1. 希望获得委托链上每个回调方法的返回值?默认情况下我们只能获得最后一次调用的回调方法的返回值。
  2. 被调用的委托中有一个抛出了异常。
  3. 被调用的委托中有一个阻塞了很长时间。

  由于委托链上的对象是按序调用的,所以如果有一个委托对象出了问题,将会阻止调用委托链上所有其他的委托对象。显然,这样的算法不够强健。

  对于那些该算法不能满足的情况,MulticastDelegate类提供了一个实例方法GetInvocationList,我们可以使用它来显式调用委托链上的每一个委托对象。

  该方法原型:

public class MulticastDelegate
{
//创建一个委托数组,每一个元素都是委托链上对象的一个克隆
//第0个元素是链表的尾部,通常的会被首先调用。
public virtual Delegate[] GetInvocationList();
}

  GetInvocationList方法会遍历指定的委托链,然后为委托链上的每一个对象创建一个克隆体,并将其添加在数组中。其中每个克隆体的_prev都会被设为null,所以每个元素都是孤立的。通过该方法,我们可以很容易编写一个算法来显式调用数组中的每个对象。

动态创建与调用委托

  某些情况下,开发人员在编译时并不知道回调方法的原型。System.Delegate提供了几个方法允许我们在编译时不知道回调方法原型的情况下仍能创建并调用一个委托。下面是Delegate定义的这些方法:

public class Delegate
{
//创建一个封装MethodInfo的delType委托
public static Delegate CreateDelegate(Type delType, MethodInfo mi);

//创建一个封装静态方法的delType委托
public static Delegate CreateDelegate(Type delType, Type type, string methodName);

//创建一个封装实例方法的delType委托
public static Delegate CreateDelegate(Type delegateType, object obj, string methodName);

//创建一个封装实例方法的delType委托
public static Delegate CreateDelegate(Type delegateType, object obj, string methodName, Boolean ignoreCase);

//在运行时传递一组参数来调用一个委托对象的回调方法
//它在内部确保传递的参数和回调方法期望的参数兼容
public object DynamicInvoke(object[] args);
}
posted on 2011-03-29 22:49  辛勤的代码工  阅读(336)  评论(0编辑  收藏  举报