第二部分 设计类型:第11章 事件

事件是实现交互的类型成员。


定义事件需要提供以下能力:
1.方法可登记/注销它对该事件的关注。
2.改事件发生时,登记了的方法会收到通知。

类型之所以能提供事件通知功能,是因为类型维护了一个已登记方法的列表。事件发生后,类型将通知列表中所有已登记的方法。

为了理解事件在CLR中的工作机制,举个实用的场景:
假定要设计一个电子邮件程序。电子邮件到达时,用户希望将该邮件转发给传真机或寻呼机。
构建这个应用程序时,假定先设计一个名为MailManager的类型,负责接收传入的电子邮件。MailManager类型公开了一个名为NewMail的事件。其他类型(如Fax和Pager)的对象可登记它们对这个事件的关注。MailManager收到信邮件时,会引发该事件,将邮件分发给每一个登记的对象。

应用程序初始化时,只实例化一个MailManager实例。然后,应用程序可实例化任意数量的Fax和Pager对象。

 

11.1 设计要公开事件的类型

11.1.1  第1步:定义类型来容纳所有需要发送给事件通知接收者的附加信息
事件对象想向接收通知的对象传递一些附加信息,那么需要封装到自己的类中,包含私有字段和只读公共属性。根据约定,这种类型应该从System.EventArgs类派生,并且类名以EventArgs结束。

//首先 定义类型来容纳发送给接受者的附加信息

internal class NewMailEventArgs:EventArgs{

  //附加信息的私有字段

  private readnoly string m_from,m_to,m_subject;

 

  //附加信息的只读属性

  public string From{ get{return m_from;}}

  public string To{ get{return m_to;}}

  public string subject { get{return m_subject;}}  

 

  public NewMailEventArgs(string from,string to,string subject){

     m_from = from; m_to = to; m_subject = subject;

  }

}



//后续的步骤在MailManager类中进行

internal class MailManager{

}

 


11.1.2  第2步:定义事件成员
事件成员使用event关键字来定义。


每个事件成员要指定一下内容:
1.一个可访问性标示符(public)。
2.一个委托类型,它指出要调用的方法的原型。
3.一个名称(可以是任意有效的标示符)。

MailManager类的事件成员:

internal class MailManager{

  //第2步:定义事件成员

  public event EventHandler<NewMailEventArgs> NewMail;

  ...

}


NewMail是这个事件的名称。
事件成员的类型是EventHandler<NewMailEventAgrs>,意味着“事件通知”的所有接受者都必须提供一个原型和EventHandler<NewMailEventArgs>委托类型匹配的回调方法。

由于泛型System.EventHandler委托类型的定义如下:

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

   where TEventArgs: EventArgs;

所以方法原型必须具有以下形式:

void MethodName(Object sender,NewMailEventArgs e);

你可能感兴趣的:(事件)