事件模型准则
下面的准则中斜体字“ Custom” 是自定义部分,请用你的实际名称来代替。
- 事件的名称应该采用PascalCasing 命名方式,以 Custom Event命名。
- 声明事件委托时,使用void 类型返回值, Custom Event事件的委托是 Custom EventHandler,事件委托接受两个参数,一个是事件源对象,另一个是事件数据,一律命名为 sender 与 e 。
- 定义一个提供事件数据的类,在类内部定义要传递的数据。应该从System.EventArgs 类派生该类,以 Custom EventArgs进行命名,。即使我们确定不需要向事件处理程序发送事件数据,也应该派生一个空的事件数据类,这样做可以在以后的版本中部引入重大更改的情况下想事件添加数据。
下面是一个例子:
//事件数据类
public class PublisMagazineEventArgs : EventArgs { }
//事件委托
public delegate void PublishMagazineEventHandler ( Publisher sender , PublisMagazineEventArgs e );
- 在引发事件的类中声明一个受保护的虚方法来触发事件。以On Custom Event进行命名,并接受一个事件数据类对象作为参数,命名为 e 。遵循从准则可以使派生类能够通过重写受保护的方法来处理基类事件。
- 触发事件永远发生在事件源类里面。
下面是个例子:
//触发事件的方法
protected virtual void OnPublishMagazineEvent (
PublisMagazineEventArgs e )
// 在这个方法内触发事件
public void DoPublish ( string magazineName , string date )
{
// 做一些其它的事情
//触发事件
OnPublishMagazineEvent ( new PublisMagazineEventArgs ());
}
- 在事件监听者类中声明事件处理方法,以HandleCustom Event命名,方法签名必须跟事件委托标识的签名相同。
public void HandlePublishMagazineEvent ( Publisher sender ,
PublisMagazineEventArgs e )
一些其它准则:
当引发非静态事件时,不要将 null(在 Visual Basic 中为 Nothing)作为 sender 参数进行传递。
对于静态事件,sender 参数应该为 null(在 Visual Basic 中是 Nothing)。
当引发事件时,不要将 null(在 Visual Basic 中为 Nothing)作为事件数据参数进行传递。
如果没有事件数据,则传递 Empty ,而不要传递 null。
事件处理方法中会发生任意代码执行,对此一定要做好准备。
考虑将引发事件的代码放置在 try-catch 块中,以防止由事件处理程序引发的未处理异常所导致的程序终止。
考虑引发最终用户可以取消的事件。这仅适用于事前事件。
如果您正在设计可取消的事件,请使用 CancelEventArgs (而非 EventArgs )作为事件数据对象 e 的基类。
一个完整例子:出版社与订阅者
下面这个简单的例子用来说明如何定义和使用事件,以及运用上面的准则。