zoukankan      html  css  js  c++  java
  • C#中事件机制的理解

    引自:http://www.csharpwin.com/csharpspace/2793.shtml

    前些天狠狠心咬咬牙,从刚发的工资中拿出几十块大洋,又给老外投资了一笔,呵呵,还好投资方向没错,物超所值啊拥有了一本Jeffrey Richter前辈的<Microsoft .net框架程序设计>,现在已经看完前17章了,可谓是进展神速啊(小小滴自夸一下)
    昨天和今天两天好好的把"委托"机制研究了一下,算是小有所明白了,想起来前些天看"事件"的时候,因为其中也涉及到了委托机制,所以都看得有些云里雾里的
    第一遍看的时候,大多数地方都还看得明白,但是有个地方就一直没转过来.
    书上说的是,定义了一个类以后,例如书中的例子是class  MailManger(注意:该MailManger类之内还有一个描述mail消息的class MailMsgEventArgs,也就是用来定义保存mail消息的东东,同时也是一个继承自EventArgs的类型,这是根据.net框架约定 的),这里,先贴一下它的代码

    public class MailMsgEventArgs:EventArgs
     2{
     3public MailMsgEventArgs(String from,String to,String subject,String body)
     4{
     5this.from=from;
     6this.to=to;
     7this.subject=subject;
     8this.body=body;
     9}
    10public readonly String from,to,subject,body;
    11}

    很明显,是一个用来描述的类型,具体没有多少内容,
    然后,紧跟着又定义了一个委托,已经用这个委托类型(这里要插一句的是,我看完第十七章才知道委托在.net框架内部就是一个类型,所以才可以定义它的一个对象)来定义了一个事件对象(我现在的看法是,该事件对象也就是相当于一个class的对象)
    delegate void MailMsgEventHandler(Object sender,MailMsgEventArgs args);
    2
    3public event MailMsgEventArgs MailMsg;

    //should be 'public event MailMsgEventHandler MailMsg;' sorry:)
    其中有一些定义事件委托的代码规范是要注意一下的.
    到这里就开始有点迷糊了,为什么就一定要这样用个委托转个弯来定义一个事件呢??
    然后后文就开始谈到说,定义事件的这个类(在这里是MailManger)允许其他类的对象(书中的例子是Fax和Printer)登记该事件,然后在有 特定事件发生时(也就是这里的MailMsg事件),由事件宿主MailManger来通知它的事件登记者,告诉它们采取措施,例如Fax就应该立即 fax一份传真出来,打印机也就得老老实实的打印东东出来(嗯,看来这个事件机制真的很牛
     在后文中,就具体说明了MailMsg的工作机制,原来是C#编译器看到有这么一句以后,就把它翻译成三个构造,如下:
    private MailMsgEventHandler MailMsg=null;
     2//我认为这里就是关键了,也就是指定了委托对象的头指针
     3
     4[MethodImplAttribute(MethodImplOptions.Synchronized)]
     5public virtual void add_MailMsg(MailMsgEventHandler handler)
     6{
     7MailMsg=(MailMsgEventHandler)Delegate.Combine(MailMsg,handler);
     8}
     9
    10[MethodImpl(MethodImplOptions.Synchronized)]
    11public virtual void remove_MailMsg(MailMsgEventaHandler handler)
    12{
    13MailMsg=(MailMsgEventHandler)Delegate.Remove(MailMsg,handler);
    14}

    仔细看了委托那一章的后几节才明白,实际上委托都是继承自MultiDelegate类型,而MultiDelegate又继承自Delegate类型, 而Delegate类型定义了两个方法(这里的virtual是不应该有的),其中的add方法就是把委托对象添加到委托链上,而remove方法则是把 委托对象从委托链上移出,没看委托一章时,虽然大致上明白这里两个方法的含义,但是不明白它们的真正内涵之所在.
    前思后想,终于明白其中的真谛之所在,由于Delegate的机制,add了一个委托对象以后,就相当于在这个委托链上增加了一个委托对象,remove 了一个委托对象以后,就相当于在这个委托链上移出了一个委托对象,可以把这里的委托链理解为数据结构中的链表(我就是这么理解的),要对该委托链表进行操 作,只需要找到链表的尾巴(这里是tail,而不是head,可以从Delegate的重载方法中看出),然后依次进行操作.直到该委托链上的所有对象都 有操作完毕.
    最开始一直不理解的是:因为虽然在Fax类型中确实把自身登记到该事件中去了,但是这个事件宿主是怎么知道都有谁已经登记了呢?如果不知道都有哪个对象已经登记了该事件,那又怎么去轮个通知呢?
    看完了之后,才总算了解了委托的伟大之所在.
    其实我认为最明白的想法就是,由事件宿主来维护一个委托对象(也就是它自己定义的事件,这里必须是一个委托对象),并且同时有该委托类型的一个对象(这里 肯定是一个引用对象),在事件登记者都已经操作完毕之后,也就是把自己添加到该委托对象的屁屁后面以后,该事件宿主只需要通知一个人,也就是它自己维护的 那个委托对象,因为是指针形式,就会自动也把自己屁屁后面的跟屁虫挨个都通知到,这样就达到了通知所有事件登记者的目的。
  • 相关阅读:
    判断两个数组是否相等
    正则表达式的正向预查
    IFC布局特点
    XSS攻击总结
    String与toString
    link与@import
    BFC布局
    单例模式
    <input type="radio" >与<input type="checkbox">值得获取
    Struts标签<s:iterator>遍历访问复杂Map对象
  • 原文地址:https://www.cnblogs.com/nearpengju123/p/4301754.html
Copyright © 2011-2022 走看看