关于Delegate 和 MulticastDelegate的实现

在C#中,我们使用关键字delegate来定义委托,如:
public delegate void MyDelegate(object obj, int x);
在进行编译时,以上的代码将产生一个类定义:
public class MyDelegate : System.MulticastDelegate {
       public MyDelegate(Object target, IntPtr methodPtr);
       public void virtual Invoke(object obj, int x);     // 和委托中的参数一样.
       public virtual IAsyncResult BeginInvoke(object obj, int x, 
             AsyncCallback callback, object o);
       public virtual void EndInvoke(IAsyncResult result);
}
在以上代码中,构造函数中的参数:target 为对象实例的引用,methodPtr为用来标识回调方法。MulticastDelegate继承自Delegate,实际上Delegate类有四个私有字段:
1、private Object _target;
2、private IntPtr _methodPtr;
3、private IntPtr _methodPtrAux;
4、private RuntimeMethodInfo _method;
其中_target是调用方法的对象实例的引用,如果调用方法是static的,那么就不存在对象实例的引用,这时target为null。_methodPtr是用来标识要调用的方法。
在上面的MyDelegate委托中,MyDelegate的构造构数就是将_taget和_methodPtr进行初始化。

而 在MulticastDelegate类中,增加了一个私有字段:private MulticastDelegate _prev;这个_prev字段指向的是一个MulticastDelegate类型的引用,也就是说利用指向另一个MutlicastDelegate 类型的_prev字段来组成一个委托链表。
如果要向委托链表中增加和删除委托,C#中使用以下语法实现:
MyDelegate myDelegate = new MyDelegate(DelegateMethod1);
myDelegate += new MyDelegate(DelegateMethod2); //添加(Delegate.Combine) 
myDelegate -= new MyDelegate(DelegateMethod2); // 删除(Delegate.Remove)

在 新增一个委托到委托链表时,MyDelegate类的构造函数将调用基类MulticastDelegate的构造函数,将字段_target 和 _methodPtr初始化,并将MulticastDelegate的_prev字段初始化为null.在调用Remove方法时,它也会构造一个 MyDelegate的实例,也会初始化基类的_target、_methodPtr、和_prev字段。构造完后,Remove方法会先扫描委托链表, 如发现有和新创建的委托对象相等的委托对象,则将它从链表中删除,如没有找到,则不作做任何操作。

(0)

相关推荐

  • .Neter所应该彻底了解的委托

    本文将通过引出几个问题来,并且通过例子来剖析C#中的委托以及用法,做抛砖引玉的作用 对于委托我发现大部分人都有以下问题,或者可能在面试中遇过这样的: 委托是不是相当于C/C++的函数指针? 委托究竟是 ...

  • 当你问代理机制的时候?指的是Agent,Proxy,Broker还是Delegate呢?

    正如人们在各种日常活动中存在着形形色色的代理机制一样,在计算机科学领域,代理机制乃是解决各种复杂难解问题的基本途径之一. 小到对象/实体之间的通信,大到子系统.系统乃至超系统的设计,都会应用到代理.应 ...

  • C# 委托Delegate(一) 基础介绍&用法

    本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...