事件,不知道你是否有也这样理解

目录

  • 事件的特点。
  • 邮件实例及编译器如何对待事件
  • 总结

一、事件

public event EventHandler<NewMailInfo> NewMail; 
  • public    其他类可以根据规则进行注册和注销。
  • event     我觉得就是一种标识符,编译器可以进行识别,进而生成相关事件代码。
  • EventHander   泛型委托

    public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

事件是类的成员,它的出现给类提供了一种能力—-通知其他对象发生了什么。

事件是一种特殊的委托。其他对象符合规则的方法可以注册和注销事件的关注。

二、邮件实例

需求:当收到新邮件时,同时通知转发给传真机以及其他机器,使得他们可以根据自己的方式处理新邮件

1、邮件信息类:承载邮件相关信息,继承EventArgs

    public class NewMailInfo:EventArgs
    {
        private readonly string msg, from, to;
        public string Msg { get { return msg; } }
        public string From { get { return from; } }
        public string To { get { return to; } }
        public NewMailInfo(string _from, string _to, string _msg)
        {
            msg = _msg;
            to = _to;
            from = _from;
        }
    }

2、邮件管理类:负责接收新邮件,并通知注册的其他类(如:传真机、打印机等)
首先,定义一个处理新邮件方法,将相关信息赋予邮件信息承载类,并调用通知方法。

        public void SimulateNewMail(string from, string to, string msg)
        {
            NewMailInfo e = new NewMailInfo(from, to, msg);
            OnNewMail(e);
        }

其次,新邮件通知功能,通知其他注册类。

        public event EventHandler<NewMailInfo>  NewMail;
        protected virtual void OnNewMail(NewMailInfo e)
        {
            EventHandler<NewMailInfo> temp = System.Threading.Interlocked.CompareExchange(ref NewMail, null, null);
            if (temp != null)
                temp(this, e);
        }

当编译器遇检测到 event 关键字时,会将事件:

public event EventHandler MsgEvent;

翻译成三部分

1、

private EventHandler<NewMailInfo> _newmail = null;
  • 委托引用链,用于存储最终注册的方法引用。
  • 私有委托,private防止外类的修改。
  • 后面的add() 和 remove()方法,用于向这个委托引用链添加和删除引用。

2、

 public void add_NewMail(EventHandler<NewMailInfo> value)
        {
            //当前委托链
            EventHandler<NewMailInfo> newmail = this._newmail;
            EventHandler<NewMailInfo> prevHandler;
            do
            {
                prevHandler = newmail;
                EventHandler<NewMailInfo> newHandler = (EventHandler<NewMailInfo>)Delegate.Combine(prevHandler, value);
                newmail = System.Threading.Interlocked.CompareExchange(ref this._newmail, newHandler, prevHandler);
            } while (newmail != prevHandler);
        }
  • 编译器生成add_NewMail(EventHandler<NewMailInfo> value)方法
  • 将当前的委托链备份一份。EventHandler<NewMailInfo> newmail = this._newmail;
  • 循环体内,EventHandler<NewMailInfo> newHandler = (EventHandler<NewMailInfo>)Delegate.Combine(prevHandler, value);将当前需要注册的方法引用追加到委托链 prevHandler,并生成新的委托链  newHandler
  • newmail = System.Threading.Interlocked.CompareExchange(ref this._newmail, newHandler, prevHandler); 当前this._newmail,与prevHandler 引用实例是否一样。如果一样就将 newHandler的值赋值给this._newmail。

3、类似add功能 的remove()方法。

整个邮件管理类就可以这样实现了。

    public class MailManager
    {
        public event EventHandler<NewMailInfo>  NewMail;
        protected virtual void OnNewMail(NewMailInfo e)
        {
            EventHandler<NewMailInfo> temp = System.Threading.Interlocked.CompareExchange(ref NewMail, null, null);
            if (temp != null)
                temp(this, e);
        }
        public void SimulateNewMail(string from, string to, string msg)
        {
            NewMailInfo e = new NewMailInfo(from, to, msg);
            OnNewMail(e);
        }

    }

3、其他类如何注册

   public class Fax
    {
        public Fax(MailManager mm)
        {
            mm.NewMail+=FaxMsg;
        }
        public void FaxMsg(object sender, NewMailInfo e)
        {

            Console.Write(e.Msg+"【来自传真机】");
        }
    }

当前使用+=进行注册,其实也是也是用add()方法进行注册方法引用。

三、总结

  • 编译器遇到event这个标志会进行翻译。一个私有的委托,向外开放注册add和注销remove方法。事件只能当前类进行修改,对外只提供注册和注销方法。
  • 拥有事件的类在触发事件就会调用这个委托所维护的新的方法列表对方法进行回调,理所当然的拥有了通知其他对象的能力。
  • 外部类通过注册事件,可以得到通知,并进行属于自己方式的处理。
时间: 2024-10-20 01:32:40

事件,不知道你是否有也这样理解的相关文章

委托,不知道你是否有也这样理解(二)

目录 泛型委托 简化语法 委托与反射 相关文章链接: 事件,你是否也这样理解  http://www.cnblogs.com/sunchong/p/sunchong.html 委托,你是否也这样理解(一) http://www.cnblogs.com/sunchong/p/3480612.html 一.泛型委托 我们知道泛型能够提高效率,避免代码重复,灵活. C#提供了无返回值的泛型委托:Action public delegate void Action<in T>(T obj); 从上我们

关于android中事件传递和分发的一些小理解

android中 当我们的手指触摸屏幕将产生一个事件, (假设 这个过程中如果没有显示的去拦截该事件的话)   这个事件会逐级传递到视图的最底层,即使在中间某些视图会响应这个事件( 这个视图也不会去消费这个事件),     仍然是会传递到底层(底层不响应该事件),然后再由底层回传到顶层,在传回顶层的过程中 ,   原先会响应该事件的视图才会去消费这个事件 例如在左图中                                 A                               

委托,不知道你是否有也这样理解(一)

目录: 什么是委托 委托的作用 委托的本质 委托链 委托链返回值 一.什么是委托? 委托:将符合规则的方法进行包装.装载方法引用的盒子.将方法作为参数传递. class Program { static void Main(string[] args) { StaticDelegateDome(); } //定义没有返回值委托Feedback,需要一个数值类型参数 internal delegate void Feedback(Int32 value); //方法群:静态.静态.实例 priva

【转】Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9153761 记得在前面的文章中,我带大家一起从源码的角度分析了Android中View的事件分发机制,相信阅读过的朋友对View的事件分发已经有比较深刻的理解了. 还未阅读过的朋友,请先参考 Android事件分发机制完全解析,带你从源码的角度彻底理解(上) . 那么今天我们将继续上次未完成的话题,从源码的角度分析ViewGruop的事件分发. 首先我们来探讨一下,什么是View

[转]as3事件流机制彻底理解

题记: 看过网上一些as3事件流的教程,觉得大多都讲得不甚清楚,让人不能喝很直观的理解.而这篇教程以将事件流过程比喻成捕鱼过程,形象简单. 在此基础上对于as3事件流总算有了全面的理解.事件流机制说白了就是为了能让开发者能更好地控制事件调用顺序. addEventListener(type:String, listener:Function, useCapture:Boolean= false, priority:int= 0, useWeakReference:Boolean= false):

事件引入和本质

前言 继上一篇委托后,我们继续来探讨事件,因为委托和事件有着不可分割的关系.通过本文,相信你会对事件有更深刻的认识和理解,不信,你看! 概念 用event 关键字使您可以声明事件. 事件是类在相关事情发生时发出通知的方法.[简述]事件就是类在发生其关注的事情的时候用来提供通知的一种方式. 引入 要理解事件必须要先知道一下两个角色: 发行者(Publisher) 事件发行者,也称为发送者(sender),说白了就是一个对象,这个对象会自身维护本身的状态信息.当自身状态信息发生变动时,就触发一个事件

C#基础系列——再也不用担心面试官问我“事件”了

前言:作为.Net攻城狮,你面试过程中是否遇到过这样的问题呢:什么是事件?事件和委托的区别?既然事件作为一种特殊的委托,那么它的优势如何体现?诸如此类...你是否也曾经被问到过?你又是否都答出来了呢?上两篇由浅及深介绍了下委托的用法,这篇还是来说说事件.希望通过这篇的介绍,博友能有个系统的认识,至少应付面试没问题了吧.不信?瞧瞧去~~ C#基础系列目录: C#基础系列——Linq to Xml读写xml C#基础系列——扩展方法的使用 C#基础系列——序列化效率比拼 C#基础系列——反射笔记 C

UseCase事件流描述规范

文/fasiondog 整理需求用例的编写规范,分享部分UseCase事件流描述规范.其中,准则5~10.12来自<编写有效用例>([美] Alistair Cockburn 著)一书,其它为自身实践和要求. 事件流包含正常事件流.可选事件流.异常事件流程,前述三者合在一起的本质就是用文字描述的流程.事件流由文字描述的步骤组成,写作过程中应遵循以下准则,这些准则是对用例写作过程中的常见问题和最佳实践的总结.下述规范中如没有特殊说明,事件流同时指正常事件流.可选事件流.异常事件流. 准则1:文字

C#学习总结 事件(一)深入多播委托

好久没写文章了,之前说要总结一下事件这个概念,今天趁着工作闲暇,谈谈我对C#事件事件的理解,如果有什么不对的地方,望各位大神指点. 真正的理解事件,还是要很好的理解委托,不然你永远不会明白很多教科书上的一句话:事件是一个特殊的委托,今天我们就来探寻一下:为什么说事件是一个特殊的委托,之前我谈论了委托的一些相关基础知识,其实还有一些关于委托更深层次的东西没有说,那么在今天谈事件这个知识之前还是继续从委托说起: 不知道有没有人了解C语言的函数指针这个概念,使用函数指针来创建回调函数,使用回调可以把函