zoukankan      html  css  js  c++  java
  • 看懂 ,学会 .NET 事件的正确姿势

    一、事件的本质
          
    举个例子你是个取向正常的青年男性,有个身材火辣,年轻貌美,腿长肤白的美女,冲你一笑,给你讲了一个ABCD羊吃草的故事。你有什么反应?
    可能你关注点在于颜值,身材,故事,故事含义。后续事情?OK,这些都没毛病。和事件有什么关系呢?以上你关注的所有东西都可以概括为信息-事件。
    她发出了一个信息,你做出了反应。 那么整个事件的运行机制就完成了。
       简单的说就是 :一个对象发出消息,另外的对象做出响应。
       如图:

       那么再具体的详细的讲解不如Show Code :上代码:
      

    //如果本篇幅过于难以理解那么,https://www.cnblogs.com/LiMin/p/10364867.html 这个是简单版本的可以帮助你先快速理解
    namespace ConsoleApplication4
    {
        class Program
        {
            static void Main(string[] args)
            {
                PLMM plmm = new PLMM();//漂亮妹妹
                DS ds = new DS();//屌丝
                GFS gfs = new GFS();//高富帅
                MsgEventArgs msg = new MsgEventArgs
                {
                    MsgFrom = "美女",
                    MsgTo = "取向正常的男性",
                    MsgContent = "冲你笑,讲羊吃草故事。"
                };
                msg.Register(plmm, ds, gfs);//注册
                plmm.SendMsg(msg);//发送
                Console.ReadLine();
            }
        }
        #region 收发事件消息接口
    
        /// <summary>
        /// 程序角度:事件的定义是:public delegate EventHandler<TEventArgs>(object sender, TEventArgs e);
        /// 因此:事件的接受者必须具有:void Method(object sender,TEventArgs e) 形式
        /// sender :事件的发起者
        /// TEventArgs:是事件消息体
        /// 所以接受方需要接受这 2个参数,而发送方只需要发送 消息体
        /// </summary>
        public interface IBaseEvent
        {
            event EventHandler<MsgEventArgs> MsgEvent;
    
            /// <summary>
            /// 时间的信息
            /// </summary>
            /// <param name="msgEventArgs"></param>
            void SendMsg(MsgEventArgs msgEventArgs);
        }
    
        /// <summary>
        /// 程序角度:事件的定义是:public delegate EventHandler<TEventArgs>(object sender, TEventArgs e);
        /// 因此:事件的接受者必须具有:void Method(object sender,TEventArgs e) 形式
        /// sender :事件的发起者
        /// TEventArgs:是事件消息体
        /// 所以接受方需要接受这 2个参数,而发送方只需要发送 消息体
        /// </summary>
        public interface IReceive
        {
            void ReceiveMsg(object sender, MsgEventArgs msgEventArgs);
        }
    
        #endregion
    
        #region 消息发布者
        public class PLMM : IBaseEvent
        {
            public event EventHandler<MsgEventArgs> MsgEvent;
    
            /// <summary>
            /// 负责引发事件的方法
            /// </summary>
            /// <param name="msgEventArgs"></param>
            public void SendMsg(MsgEventArgs msgEventArgs)
            {
                Console.WriteLine("身材火辣,年轻,腿长,肤白貌美的美女开始行动:{0}", msgEventArgs.MsgContent);
                Dosomething(MsgEvent, msgEventArgs);
            }
            /// <summary>
            /// 如果以PLMM 为基类可以复写该方法
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="msgEventArgs"></param>
            protected virtual void Dosomething(object sender, MsgEventArgs msgEventArgs)
            {
                EventHandler<MsgEventArgs> temp = Volatile.Read(ref MsgEvent);
                temp?.Invoke(this, msgEventArgs);
            }
        }
    
        #endregion
    
        #region 消息订阅者
        /// <summary>
        /// 程序角度:事件的定义是:public delegate EventHandler<TEventArgs>(object sender, TEventArgs e);
        /// 因此:事件的接受者必须具有:void Method(object sender,TEventArgs e) 形式
        /// sender :事件的发起者
        /// TEventArgs:是事件消息体
        /// </summary>
        public class DS : IReceive
        {
            public void ReceiveMsg(object sender, MsgEventArgs msgEventArgs)
            {
                Console.WriteLine("屌丝收到:{0}{1}。反应:受不了,得去补充营养了。", msgEventArgs.MsgFrom, msgEventArgs.MsgContent);
            }
        }
        /// <summary>
        /// 程序角度:事件的定义是:public delegate EventHandler<TEventArgs>(object sender, TEventArgs e);
        /// 因此:事件的接受者必须具有:void Method(object sender,TEventArgs e) 形式
        /// sender :事件的发起者
        /// TEventArgs:是事件消息体
        /// </summary>
        public class GFS : IReceive
        {
            public void ReceiveMsg(object sender, MsgEventArgs msgEventArgs)
            {
                Console.WriteLine("高富帅收到:{0}{1}。反应:I Need You!!!", msgEventArgs.MsgFrom, msgEventArgs.MsgContent);
            }
        }
    
        #endregion
    
        #region 事件成员-消息类
        /// <summary>
        /// 事件成员:事件的附加信息。
        /// 程序角度:事件的定义是:delegate EventHandler<TEventArgs>(object sender, TEventArgs e);
        /// 按照约定事件附加信息即消息类必须实现:EventArgs 类,
        /// </summary>
        public class MsgEventArgs : EventArgs
        {
            public string MsgFrom { get; set; }
            public string MsgTo { get; set; }
            public string MsgContent { get; set; }
            public void Register(IBaseEvent baseEvent, params IReceive[] action)
            {
                foreach (var item in action)
                {
                    if (item != null)
                    {
                        baseEvent.MsgEvent += item.ReceiveMsg;
                    }
                }
            }
        }
    
        #endregion
    
    
    }

    总结:定义事件的步骤:
    一.定义类型来容纳所有需要发送给事件通知接收者的附加信息。
    二.定义事件成员
    三.定义负责引发事件的方法来通知事件的登记对象。
    四.定义方法将输入转化为期望事件

     PS:程序Demo仅仅作为演示,其中有几处设计的不是很好。。。。。。。

     综上:事件 EventHandler<TEventArgs> 系统定义:事件是由一个对象引发因此,第一个参数为 Object ,第二个为事件消息体 TEventArgs。
    public delegate EventHandler<TEventArgs>(object sender, TEventArgs e); 
    1.因此事件接受方的,方法必须满足:void Method(object sender,TEventArgs e) 形式 因为事件定义如此
    2.按照约定:事件的消息体必须继承自:EventArgs
    3.事件就是一个方法的注册列表,可以添加,也可以删除,本例没有删除事件,自己实现吧。
    4.事件引发方法,必须有消息体。
    疑惑解析:EventHandler<TEventArgs>(object sender, TEventArgs e); 第一个参数之所以是 Object 是因为,事件引发的类型可以作为基类,被实现。要是要求由子类来引发事件,那么需要类型转化,因此定义为Object,另外这样定义别的传递了同样消息体的事件引发类也可以复用。

  • 相关阅读:
    java基础部分的一些有意思的东西。
    antdvue按需加载插件babelpluginimport报错
    阿超的烦恼 javaScript篇
    .NET E F(Entity Framework)框架 DataBase First 和 Code First 简单用法。
    JQuery获得input ID相同但是type不同的方法
    gridview的删除,修改,数据绑定处理
    jgGrid数据格式
    Cannot read configuration file due to insufficient permissions
    Invoke action which type of result is JsonResult on controller from view using Ajax or geJSon
    Entity model数据库连接
  • 原文地址:https://www.cnblogs.com/LiMin/p/7212217.html
Copyright © 2011-2022 走看看