第十一章 事件

目录

11.1 设计公开事件的类型

11.2 编译器如何实现事件

11.3 设计侦听事件的类型

11.4 显示实现事件

定义了事件成员的类型允许类型(或类型的实例)通知其他对象发生了特定的事件。

定义了事件成员的类型能提供以下功能:

方法能登记它对事件的关注

方法能注销它对事件的关注

事件发生时,登记了的方法将受到通知。

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

CLR事件模型以委托为基础。委托是调用回调方法的一种类型安全的方式。对象凭借回调方法接受它们订阅的通知。

11.1 设计公开事件的类型

11.1.1 第一步:定义类型来容纳所有需要发送给事件通知接受者的附加信息

事件引发时,引发事件的对象可能希望向接受事件通知的对象传递一些附加信息。这些附加信息需要封装到它自己的类中。根据规定,这种类从EventArgs派生。

11.1.2 第二步:定义事件成员

事件成员使用C#关键字event定义

11.1.3 第三步:定义负责引发事件的方法来通知事件的登记对象

安装约定,类要定义一个收保护的虚方法。引发事件时,类及其派生类中的代码会调用该方法。

11.1.4 第四步:定义方法将输入转化为期望事件

类还必须有一个方法获取输入并转化为事件的引发。

11.2 编译器如何实现事件

编译器编译事件会转换为3个构造:

第一个构造时具有恰当委托类型的字段。该字段是对一个委托列表的头部的引用。事件发生时会通知这个列表中的委托。

第二个构造是一个方法,允许其他对象登记对事件的关注。

第三个构造也是一个方法,允许对象注销对事件的关注。

除了生成上述3个构造,编译器还会在托管程序集的元数据中生成一个事件定义记录项。这个记录项包含了一些标志和基础委托类型,还引用了add和remove访问器方法。

11.3 设计侦听事件的类型

  1.登记对事件关注并调用方法 2.调用注销对事件的关注

11.4 显示实现事件

 为了高效率存储事件委托,公开了事件的每个对象都要维护一个集合(通常是字典)。集合将某种形式的事件标识作为键,将委托列表作为值。新对象构造时,这个集合是空白的。登记对一个事件的关注时,会在集合中查找事件的标识符。如果事件标识已在其中,新委托就和这个事件的委托列表合并。如果事件标识不在集合中,就添加事件标识符和委托。

对象需要引发事件时,会在集合中查找事件标识符。如果集合中没有找到事件标识符,表明还没有任何对象登记对这个事件的关注,所以没有任何委托需要回调。如果事件标识符在集合中,就调用与它关联的委托列表。

每天学习一丢丢
原文地址:https://www.cnblogs.com/terry-1/p/9986921.html