来园子看看自己的博客,至今方体会到白驹过隙的含义,瞅着晾在这里的那几篇可怜的蝇头小文,却已然成为时间的见证了。想想以前立下的壮志雄心,要做到学习不止,笔端也要勤耕耘,可现今自己博客的境况表现,哈哈!自己确实该怀揣点羞耻之心了,尽管可以找一大堆搪塞的理由。所以今天来涂鸦一篇小文,以慰吾心!
本文乃是前篇《学习委托(3)-----解析委托的实现机制》的延伸或扩充吧,前篇未曾详谈到的关于多播委托的内容在此和各位初学的朋友一起学习一番,当然本人水平有限,高手若有幸光临,尽可拍砖便是。进入正题,同样,为便于讨论,把前篇文章中的简单代码稍加修改写在此处:
这里关键就是CombineImpl方法了,它是一个虚方法,在MulticastDelegate类中进行了重新定义,所以到最后我们调用的是MulticastDelegate类中的CombineImpl方法,在CombineImpl方法中才真正实现了委托方法链的挂接操作。同样我们可以方便的用“-=”操作符从委托方法链中移除一个方法,正如allSay -= new goodfriend.middleSay(liyufeng.mySecondSay)所示;和“+=”操作符类似,C#编译器会把“-=”转化为对静态方法Remove的调用。当然,我们可以在代码中直接调用Combine和Remove方法,而不用C#编译器提供的操作符,来实现对委托方法链的操作。
通过上面的分析,我们可以了解到,作为基类的Delegate提供了CombineImpl等一系列的虚方法,从而子类型可以重新实现这些虚方法,只是到目前为止,微软并未从再从Delegate类继承一个独立的类型来支持单播委托,想是微软开发小组认为没有必要,而是单播与多播委托都由同一个类MulticastDelegate来支持了,如果这样的话,感觉MulticastDelegate类和Delegate类完全可以合并为一个类了;当然也需微软的工程师牛人们以后可能会研发出特殊功能的委托类型,从而保留Delegate类以便扩展。
最后再看一下关于委托方法的调用say(),很简单的一行代码,在前一篇文章中已经对委托方法的调用进行了分析,得出此处会转化为对Invoke方法的调用,需要明白的是Invoke方法并非Delegate或是MulticastDelegate中的方法,而是编译器自动生成的。如下IL代码:
我们看到,Invoke方法上贴了一个MethodImpl特性(即Attribute),通过MethodImpl特性标记Invoke方法的实现由CLR运行时提供(MethodCodeType.Runtime),至于CLR为Invoke方法提供的实现代码,以本人的水平是无从探究了,不过其中用到反射技术应该是毋庸置疑的。其实查看一下Delegate类中的方法,发现有DynamicInvoke和DynamicInvokeImpl方法,其中在DynamicInvoke中对DynamicInvokeImpl进行了调用,而在DynamicInvokeImpl方法中则是运用.NET的反射技术对委托方法进行了调用,所以我们可以猜想一下,CLR运行时应该是把对Invoke方法的调用桥接为对DynamicInvoke的调用。
OK!讨论到这里就要结束了,本文是把自己对委托的理解记录于此,希望对委托不甚了解的朋友对.NET中的这项技术有一个比较好的认识,但本文探讨的毕竟是理论,而委托在实践中应用也颇为广泛,所以运用委托解决实际问题能力,还是要靠各自日常的修炼了。
另外附上本文VB.NET代码实例,方便学习VB.NET的朋友们对照:
昵称: [登录] [注册]
主页:
邮箱:(仅博主可见)
验证码: 看不清,换一个
评论内容:
登录 注册
[使用Ctrl+Enter键快速提交评论]
Powered by: 博客园 Copyright © 李玉锋