「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」。
事件和委托
事件有很多方面和委托相似。其实,事件就好像是被简化的针对特殊用途的委托。 下面是一些关于事件的重要事项:
- 触发事件(raise) 调用(invoke) 或 触发(fire)等术语。当事件被触发时,所有注册到它的方法都会被依次调用。
- 发布者(publisher) 让事件被其他类或结构可见并使用的类或结构
- 订阅者(subscriber) 把事件和发布者关联注册的类或结构
- 事件处理程序(event handler) 注册到事件的方法
事件有私有委托
事件之所以和委托类似是有充分理由的。事件包含了一个私有委托。有关事件的私有委托需要了解的重要事项如下:
- 事件提供了对它的私有委托的结构化访问
- 与委托中的很多其他 操作不一样,对于事件我们只能添加、删除或者调用事件处理程序
- 事件被触发时,它调用委托来依次调用列表中的方法
声明事件
public event EventHandler Elaspsed;
//event 为事件的关键字
//EventHandler为委托类型,用来规定事件接受的事件处理程序
事件是成员
- 由于事件不是类型,我们不能使用new表达式来创建它的对象
- 由于事件是成员,我们必须在类或结构中声明,而不能在一段可执行代码中声明它
- 事件成员被隐式自动初始化为null
触发事件
if (Elapsed != null){
Elapsed(source, args);
}
订阅事件
要为事件添加事件处理程序,处理程序必须有和事件委托一致的返回类型和签名。
- 使用+=为事件添加事件处理程序
- 方法可以是下面的任意一个:
- 实例方法
- 静态方法
- 匿名方法
- lambda表达式
移除事件处理程序
myEvent -= EventHandle;
标准事件的用法
从事件的定义来看可以知道:委托决定了事件。所以说标准事件其实说的就是标准委托。 标准委托长得这个样子:
public delegate void EventHandle(object sender, EventArgs e);
//sender:保存触发事件的对象的引用
//e :保存有关状态对于应用程序来说是否合适的状态信息
EventHandler第二个参数是EventArgs类的对象,它声明在System命名空间中。有以下几点需要注意:
- EventArgs被设计为不能传递任何数据。它用于不需要传递数据的事件处理程序
- 如果你希望传递数据,必须声明一个从EventArgs继承的类,使用合适的字段来保存需要传递的数据
public class MyTCEventArgs:EventArgs
{
public string message;
public MyTCEventArgs(string s)
{
message = s;
}
}
使用自定义的委托:
//使用非凡性委托,即一个全新的委托
public delege void MyTCEventHandler(object sender, MyTCEventArgs e);
//使用EventHandler泛型委托的方式
public event EventHandler<MyTCEventArgs> Elapsed;