设为首页 加入收藏

TOP

进一步理解C#委托
2015-02-15 13:01:34 来源: 作者: 【 】 浏览:35
Tags:进一步 理解 委托

其实,刚开始觉得委托类型是一个比较难理解的概念,怎么也不觉得下面的"AssembleIphoneHandler"是一个类型。


?按照正常的情况,如果我们要创建一个委托类型应该是:


?但是,这种写法是编译不过的,会提示不能从"System.MulticastDelegate"派生子类。


其实,这里是编译器为我们做了一个转换,当我们使用delegate关键字声明一个委托类型的时候,编译器就会按照上面代码片段中的方式为我们创建一个委托类型。


知道了这些东西,对于委托类型的理解就比较容易了,通过delegate声明的委托类型就是一个从"System.MulticastDelegate"派生出来的子类。


下面我们通过一个例子来看看委托链的建立,以及调用列表的变化,基于前面一篇文章中的例子进行一些修改。


?我们接下来进行一下单步调试看看委托链建立的过程。


1. 当下面三句执行完成后,可以通过VS看到d1、d2和d3的详细信息





对于上面三个委托实例来说:


2. 通过"+="操作符来进行委托合并



这时,由于d4初始值为null,在使用"+="操作(Combine方法)构造委托链时,将返回另外一个参数d1,再将d1的引用赋给d4(通过"ILSpy"查看,如下图)。也就是说,这时d4将指向d1所指向的对象。



3. 继续执行委托合并,并查看d4的变化



这时可以看到调用列表的变化,_invocationList包含两个元素,分别是d1和d2.


4. 最后进行一次委托合并,把d3合并到d4中



可以看到最新的d4实例中,调用列表已经包含了d3。


注意:由于委托是不可变的,所以这里应该描述为,d3和d4的Combine 产生了一个新的委托实例,新的委托实例的调用列表是d3和d4的合并;操作完成后,d4变量将指向新的委托实例的引用。


疑问:其实在这步调试过程中有个疑问,_invocationCount的值是3,但是_invocationList中有四个元素,最后一个为null,找了一下也没发现为什么,望高手看到帮忙解答。


所以对委托链建立的方法Delegate.Combine(Delegate A, Delegate B),可以进行下面的概括:


我们可以通过Delegate类的静态方法Remove,从一个委托链中移除一个委托,这里就不做演示了。


注意:当调用Remove时,会遍历(倒序)第一个参数中的中的调用列表(_invocationList), 找到与第二个参数的_target和_methodPtr字段相匹配的委托,并将其从委托列表中移除。


当有多个匹配的情况是,Remove方法只移除第一个匹配的委托;但是,可以通过RemoeAll方法来移除所有匹配的委托。


同样对委托移除的方法Delegate.Remove(Delegate A, Delegate B),可以进行下面的概括:


通过这篇文章,进一步认识了委托类型,然后通过一个例子观察了委托链的建立以及调用列表的变化。


通过这两篇文章,对委托应该有了一定的认识:


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C#泛型中的类型约束和类型推断 下一篇理解C#事件

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: