zoukankan      html  css  js  c++  java
  • CLR VIA C#事件

    事件是类型的一个成员,用来在事情发生的时候通知注册了该事件的成员。

    事件和观察者模式十分的相似,所以事件应该提供如下几种能力

    1.能让对象的方法登记对他的关注

    2.能让对象的方法取消对他的关注

    3.能在事件发生的时候将通知发送给方法

    在C#中的某个类中定义一个事件使用如下语句

    public event EventHandler<EventArgs> SomeEvent;

    其中EventHandler<EventArgs>是一泛型委托,在System命名空间下,委托的定义为

    public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
    其中TEventArgs是这个委托所需要定义的参数,应该从System.EventArgs派生,不过你要是在想传一个字符串什么的,确实也是没问题的。一般这个变量中会传递事件希望通知给事件订阅者的一些信息。
    我们可以看见这个类什么都没有做,只是提供一种约束
        // 摘要:
        //     System.EventArgs 是包含事件数据的类的基类。
        [Serializable]
        [ComVisible(true)]
        public class EventArgs
        {
            // 摘要:
            //     表示没有事件数据的事件。
            public static readonly EventArgs Empty;
    
            // 摘要:
            //     初始化 System.EventArgs 类的新实例。
            public EventArgs();
        }


    下面我们来设计如下常景。
    我们需要一个自动回复机器人,当接收到信息中心传递来的消息后,我们需要回复'xxx,你好',xxx这个是发消息人,将通过EventArgs传过来
    首先,我们需要一个信息中心类,有登记方法,取消登记,通知的功能
    internal class MessageSender 
        {
            //一个类型为委托的私有字段,这个字段维护了一个委托列表
            private EventHandler<NewMessageEventArgs> m_NewMessage;
            //一个事件成员,用来给外部方法登记和取消登记
            public event EventHandler<NewMessageEventArgs> NewMessage 
            {
                add 
                {
                    m_NewMessage += value;
                }
                remove
                {
                    m_NewMessage -= value;
                }
            }
            //通知订阅对象,有新消息到了
            public void OnNewMessage(NewMessageEventArgs e)
            {
                if(m_NewMessage!=null)
                {
                    m_NewMessage(this,e);
                }
            }
        }

    还需要定义一个事件参数类,用来传递消息发送人的名称

     //EventArgs类,携带发送消息的人的名称传递给事件订阅者
        internal sealed class NewMessageEventArgs:EventArgs
        {
            private readonly String m_from;
            public String From{get;}
        }

    现在定义两个消息订阅类,分别提供各自的方法来订阅消息发送事件

    internal class JustSayHello
        {
            public JustSayHello(MessageSender ms)
            {
                ms.NewMessage += sayHello;
            }
            private void sayHello(object sender,NewMessageEventArgs e) 
            {
                Console.WriteLine("Hello {0}",e.From);
            }
            public void unRegistered(MessageSender ms) 
            {
                ms.NewMessage -= sayHello;
            }
        }
        internal class JustSayAloha
        {
            public JustSayAloha(MessageSender ms)
            {
                ms.NewMessage += sayAloha;
            }
            private void sayAloha(object sender, NewMessageEventArgs e)
            {
                Console.WriteLine("Aloha {0}", e.From);
            }
            public void unRegistered(MessageSender ms)
            {
                ms.NewMessage -= sayAloha;
            }
        }

    然后在静态方法中调用,

    static void Main(string[] args)
            {
                MessageSender ms = new MessageSender();
                NewMessageEventArgs e = new NewMessageEventArgs("ailijima");
                JustSayHello jsh = new JustSayHello(ms);
                JustSayAloha jsa = new JustSayAloha(ms);
                ms.OnNewMessage(e);
                Console.Read();
            }

    输出如下

     

  • 相关阅读:
    golang ssh 相关
    javascript 常用正则表达式收集
    Mac下 shell文件双击可执行怎么写
    Python常用插件之BeautifulSoup4使用
    Python常用插件之Requests使用
    JavaScript学习-WeakSet
    javascript学习-Set
    Vue-大型项目下路由的模块拆分
    360兼容模式ie10不支持includes方法
    360兼容模式ie10及以下版本map对象和Set对象没有定义
  • 原文地址:https://www.cnblogs.com/iiaijimaai/p/3313529.html
Copyright © 2011-2022 走看看