第10讲 事件2
视频讲师:陈广老师
大家好,今天我们接着上节课的内容继续讲解事件。我们首先回顾一下定义一个完整事件的四个步骤:
在事件发行者中定义一个事件
声明一个事件首先要声明一个准备跟事件关联的委托类型,接下来根据前面所声明的委托类型声明自己的事件,声明事件用even关键字。(上节代码所示)
在事件发行者中定义一个事件
声明一个事件首先要声明一个准备跟事件关联的委托类型,接下来根据前面所声明的委托类型声明自己的事件,声明事件用even关键字。(上节代码所示)
在事件发行者中触发事件
事件的触发必须通过一个过程,这个过程首先判断事件是否为空,如果不为空,就直接触发事件。它的本质就是触发一个委托链。
事件的触发必须通过一个过程,这个过程首先判断事件是否为空,如果不为空,就直接触发事件。它的本质就是触发一个委托链。
在事件订阅者中定义事件处理程序
这个事件处理的程序,必须跟委托类型相一致,也就是说它的返回值跟参数类型都必须相同。
这个事件处理的程序,必须跟委托类型相一致,也就是说它的返回值跟参数类型都必须相同。
向事件发行者订阅一个事件
订阅一个事件使用+=关键字,取消订阅使用-=。这个跟委托链是一致的。
订阅一个事件使用+=关键字,取消订阅使用-=。这个跟委托链是一致的。
接下来我们来讲一下.NET Framework事件设计准则,.NET对于事件的设计有他的一套规范,我们应该遵守这个规范。
首先,事件的命名准则应使用PascalCasing命名方式。
什么是PascalCasing命名方式呢?我们来看一下EventName这个单词,首先Event是一个单独的英文单词,它的意思是事件,Name也是一个单独的英文单词,它的意思是名称。我们一看到这2个单词组合在一次我们就可以联想到它是事件的名称,而这2个英文单词的首字母都是用大写的,通过首字母大写的命名方式,我们就可以很容易区分出2个英文单词,而这个呢就是PascalCasing的命名方式。
(声明一个事件呢要声明它对应的委托链)声明delegate时,使用void类型当作返回值(是必须使用void当作返回值,为什么呢?因为我们讲过事件它的本质是一个委托链这个委托链也包含多个代理,如果每个代理都有返回值,那它返回的是哪一个返回值呢,只能是最后一个。所以呢事件拥有返回值这也就失去了它的意义),EventName事件的事件委托是EventNameEventHandler,事件的接受两个传入参数,一律命为sender与e。
首先,事件的命名准则应使用PascalCasing命名方式。
什么是PascalCasing命名方式呢?我们来看一下EventName这个单词,首先Event是一个单独的英文单词,它的意思是事件,Name也是一个单独的英文单词,它的意思是名称。我们一看到这2个单词组合在一次我们就可以联想到它是事件的名称,而这2个英文单词的首字母都是用大写的,通过首字母大写的命名方式,我们就可以很容易区分出2个英文单词,而这个呢就是PascalCasing的命名方式。
(声明一个事件呢要声明它对应的委托链)声明delegate时,使用void类型当作返回值(是必须使用void当作返回值,为什么呢?因为我们讲过事件它的本质是一个委托链这个委托链也包含多个代理,如果每个代理都有返回值,那它返回的是哪一个返回值呢,只能是最后一个。所以呢事件拥有返回值这也就失去了它的意义),EventName事件的事件委托是EventNameEventHandler,事件的接受两个传入参数,一律命为sender与e。
定义一个提供事件数据的类,对类以EventNameEventArgs进行命名,从System.EventArgs派生该类,然后添加所有事件特定的成员。
上面是一个委托的声明,sender的类型必须是object类型,而e的类型呢它可以为EventArgs,也可以自己声明一个类,而这个类呢是从System.EventArgs派生而来,如果我们的事件需要传输一个或多个参数,这个时候我们就可以System.EventArgs派生一个类,把这些参数全部打包与EventNameEventArgs这个类里成为这个类的一个成员。当然这个类也有他的命名规范就是事件名称加上EventArgs(EventNameEventArgs)。
我们看,这里有个事件声明的例子。
上面是一个委托的声明,sender的类型必须是object类型,而e的类型呢它可以为EventArgs,也可以自己声明一个类,而这个类呢是从System.EventArgs派生而来,如果我们的事件需要传输一个或多个参数,这个时候我们就可以System.EventArgs派生一个类,把这些参数全部打包与EventNameEventArgs这个类里成为这个类的一个成员。当然这个类也有他的命名规范就是事件名称加上EventArgs(EventNameEventArgs)。
我们看,这里有个事件声明的例子。
如果事件不需要传递任何数据,这个时候也需要传递两个参数(sender,e),e参数可以直接使用系统提供的System.EventArgs类。也就是说你不需要再创建新类了。但是如果需要传递数据,则要从System.EventArgs继承一个类,并把数据放在里面。
下面呢我们就把上节课的所做的例子按照规范进行下改写。在修改中,还有个设计准则:
在引发事件的类中提供一个受保护的方法。以OnEventName进行命名。在该方法中引发该事件
下面呢我们就把上节课的所做的例子按照规范进行下改写。在修改中,还有个设计准则:
在引发事件的类中提供一个受保护的方法。以OnEventName进行命名。在该方法中引发该事件
virtual
表示一个虚方法,它的子类可以重写这个方法。在方法体内直接引发事件。
修改代码如下:
修改代码如下:
执行我们规范过的代码,效果如下:
好,正常显示,和上节课的基本相同,只是添加了出版时间的显示。我们花了一节课的时间把我们第一节课所做这个事件的程序做了一个规范化。可能有些人会有疑问了,有没有必要花那么多的时间去规范化的去编写呢?这是非常有用的,而且也非常值得。如果所有程序员都按照一个规范来写程序,那么在你看别人代码的时候就会变的非常容易,所以呢我们要尽量按照规范写程序。
好,这节课的内容就讲到这里。

好,正常显示,和上节课的基本相同,只是添加了出版时间的显示。我们花了一节课的时间把我们第一节课所做这个事件的程序做了一个规范化。可能有些人会有疑问了,有没有必要花那么多的时间去规范化的去编写呢?这是非常有用的,而且也非常值得。如果所有程序员都按照一个规范来写程序,那么在你看别人代码的时候就会变的非常容易,所以呢我们要尽量按照规范写程序。
好,这节课的内容就讲到这里。
由快乐乔巴听课摘写笔记