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(); }
输出如下