.net Delegate (二):揭秘

.net中定义了2种不同类型的委托:单播委托System.Delegate和多播委托System.MulticastDelegate.  


System.MulticastDelegate继承自System.Delegate。 System.Delegate用于不可以被链接在一起的委托对象;MulticastDelegate可以链接多个委托对象。



而在实际中,我们创建的所有委托类型都是以MulticastDelegate为基类的。(因为MulticastDelegate继承自Delegate,后者的2个静态方法Combine和Remove也经常使用。)
由此可知,我们创建的委托都允许维护一个委托链表,将回调方法或者说此委托类型的实例放到委托链表中。通过重载的操作符:+=和-=可以完成上链和移除的操作,其背后就是调用Combine和Remove方法。

在class MouseFamily中定义的委托:
    class MouseFamily
    {
        //定义Feedback委托类型
        public delegate void Feedback(string mouseName, int num);
        private string[] mice;
        public MouseFamily(string[] mouseName)
        {
            mice=new string[mouseName.Length];
            for (int i = 0; i < mouseName.Length; i++)
                mice[i] = mouseName[i];
        }

        public void Run(Feedback feedback)
        {
            for (int i = 0; i < mice.Length; i++)
            {
                if (feedback != null)
                    feedback(mice[i], i + 1);
            }
        }
    }

编译器遇到public delegate void Feedback(string mouseName, int num);这句时,会产生如下一个类的定义:

     public class Feedback : System.MulticastDelegate {
            //构造函数
            public Feedback(Object target,Int32 methodPtr);

            //类似于函数的签名,和原型函数一致
            public void virtual Invoke(string mouseName,Int32 num);

            //允许进行异步的回调
            public virtual IAsyncResult BeginInvoke(string mouseName,
                Int32 num,
                AsyncCallback callback,Object object);

            //等待异步的返回
            public virtual void EndInvoke(IAsyncResult result);
        }
ILDasm查看:


Delegate类有四个私有字段:
1、private Object _target;
2、private IntPtr _methodPtr;
3、private IntPtr _methodPtrAux;
4、private RuntimeMethodInfo _method;
其中_target是调用方法的对象实例的引用,如果调用方法是static的,那么就不存在对象实例的引用,这时target为null。_methodPtr是用来标识要调用的方法(一个特殊的标识方法的Int32值)
在上面的Feedback委托中,Feedback的构造构数就是将_taget和_methodPtr进行初始化。


MulticastDelegate类自己增加了个私有字段:
private  MulticastDelegate _prev;
_prev用于指向另一个委托对象,实现链表。


当回调方法时,feedback+=new MouseFamily.Feedback(Tom.Cry)
回调方法产生的代码像编译下面的代码一样
feedback.Invok(mouseName,num);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值