欢迎来到天天文库
浏览记录
ID:42062237
大小:49.05 KB
页数:5页
时间:2019-09-07
《.NETFramework源码研究系列之1---Delegate》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、・■、〈—i--.曾几何时能看到微软产品的源码简直是天方夜谭,不过现在这却成了现实,微软终于对外开放了它的产品的源代码•抛去开源运动与微软之间的世代情仇,抛去微软这一做法的初衷,这总归是件好事,能够让我们拨开云雾,一窥优秀产品的秘密.前两天看到有位仁兄在随笔中的留言,说他以为〃・NET中的设计模式〃是在讲.NETFramework与设计模式的关系,其实不是,不过这也让我想起来自己确实研究过.NETFramework的源码于是就找打算找时间把自己的心得体会拿出来和大家一起分享.今天就先从最容易让人困惑的委托(delegate)开始,让我们步入.NETFramework源码世界,共同学习优秀的程序
2、设计.先看委托的定义:用于声明一个引用类型,该引用类型可用于封装命名方法或匿名方法。委托类似于C++中的函数指针;但是,委托是类型安全和可靠的。相信看到这段话Z后,很多人,包括我自己就开始一起探索委托与函数指针,于是各种网文就出现了•但委托到底是什么呢?我们先看一段很简单的代码:publicdelegatevoidOnAction(intflag);这里我们定义了一个最简单的委托:0nAction.MSDN解释Delegate类是委托类型的基类,但只有系统和编译器可以显式地从Delegate类或MulticastDelegate类派生.那么我们可以认为OnAction是从delegate继承过
3、来的,只是不能显式的继承,由系统代做了.接下来让我们看一下微软是怎么定义委托的:[SerializableO][ClassTnterface(ClassTnterfaceType.AutoDual)][System・Runtimc.IntcropScrviccs・ComVisiblc(true)]publicabstractclassDelegate:1C1oneable,ISerializable由此可以看岀delegate是个抽象类,并且实现了ICloneable,ISerializable两个接口,并且有Classinterface(ClassInterfaceType.AutoDual
4、)这么一个属性•这有很多问题.首先,委托是个抽象类,所以要使用的必须继承,但是委托又跟整型一样,是一种类型,由此就可以理解问什么"Delegate类是委托类型的基类,但只有系统和编译器可以显式地从Delegate类或MulticastDelegate类派生"这句话的意思了,因为不可能从整型继承过来一个子类,那么委托为什么是一个类而不像整型一样是一个结构呢?这个问题下面回答.其次,这也是我觉得不理解的地方,委托实现了ICloneable,ISerializable两个接口,也就是说委托可以被克隆和序列化•相信大家没人会写OnAction.Clone();这么一句话•浅表克隆一个委托实在有点费解.
5、不过,如果可以从良好的编程习惯上解释为什么事先TCloneable接口的话,委托对ISerializable的实现就更让人困惑了,因为可能因此导致一些莫名其妙的编译时错误•我曾经遇到这样一个Bug,一个标记序列化的单件实体类包含一个事件(事件默认实现了ISerializable),该事件导致序列化的时候在凡是跟该事件的引用有关的地方全部报出莫名其妙的未标记序列化的错误,最终的解决办法是需要将该事件标记为[NonSerialized]・下面看一下具体是怎么实现委托的:匚代码publicabstractclassDelegate:IC1oneable,ISerializable{//要调用的对彖i
6、nternalObject_target;//MethodBase,eithercachedafterfirstrequestorassignedfromaDynamicMethodinternailMethodBase_mcthodBasc;//methodPtrisapointertothemethodwewillinvoke//ItcouldbeasmallthunkifthisisastaticorUMcallinternalTntPtr_methodPtr;//Inthecaseofastaticmethodpassedtoadelegate,thisfieldstores//wha
7、tevermethodPtrwouldhavestored:andmethodPtrpointstoa//smallthunkwhichremovesthe〃this〃pointcrbeforegoingon//to_methodPtrAux.internalIntPtrmethodPtrAux;//Thisconstruetoriscal1edfromtheclassgeneratedbythe
此文档下载收益归作者所有