C#事件处理程序的写法

时间:2022-08-30 21:18:54

事件的概念

原则:

1、C#事件本质就是对消息的封装,用作对象之间的通信;发送方叫事件发送器,接收方叫事件接收器;

2、发送器不知道接收器的任何情况,但接收器有一个事件处理程序来处理这个事件(当事件发生时);那么发送器和接收器之间如何进行通信呢?用事件,用委托,简单地来理解把事件理解成消息即可。

先定义个委托,要使用的事件处理程序的签名(也就是函数类型,返回值,参数个数,参数类型等等)由这个委托定义,委托本质就是个函数指针,指向指令所在的内存区域。

      C#事件处理程序的写法

      事件+=委托(事件处理程序)

      把这个事件委托给了事件处理程序

      至于事件处理程序的签名是怎么样的,由委托给出,EventHandler委托是由系统所定义的。

 

      所以总的流程,是这样的:

      1)先定义个委托,不一定在接收器的内部,在可见域即可

      2)在发送器类对象的内部来进行注册,进行委托,把事件和事件处理程序关联起来(事件处理程序可以是静态的,直接用;可以是非静态的,用实例化对象才能调用,因为这种成员函数是属于类实例对象的,只有实例化的对象调用才有意义,也可以理解成为,实例化对象之后才编译出这种函数的指令代码放在内存中,才能有效引用,这种是否和静态函数一样是否预先编译取决于编译器及系统的综合考量设计),在接收器方面,给出事件处理程序的实现。

 

3、

 

C#事件处理程序的写法

 

4、可给一个事件添加多个事件处理程序,仍类似于多播委托,多个事件处理程序的顺序是不一定的,所以就不能编写事件处理程序之间互相有顺序依赖的程序

C#事件处理程序的写法

 

 5、一种简化写法,不必给出事件处理程序(消息处理函数),在事件委托给事件处理程序处,直接用入表达式给出事件处理程序的代码块

C#事件处理程序的写法

 

 6、

C#事件处理程序的写法

 

事件定义的时候,其语法形式需要指出所用的委托(一种类类型,一种函数指针的类型,带有签名检查,返回值,参数类型,参数个数等等),一般使用系统内置的委托,所以就不用单独给出了;

委托的参数用的是规定好的形式,void返回类型,两个参数,一个参数object sender,一个参数是有关事件的其他有用信息的类对象,可以是任意类类型,但是必须派生于EventArgs类(派生于的一个基类,为了多态扩展,可以使用任何未知类型,用一定义好的函数格式)

在接收器,给出满足这个委托格式(这个事件处理函数格式)的函数,也就是事件处理程序的实现即可。


原则:

1、sender是一个object定义类型,利用oo多态的功能,
父类引用一个子类实例化对象完全可以,在执行的时候
解析成个子类的对象,当然要调用子类扩展的成员时
直接用sender不行,因为毕竟在形式上是父类类型,父类里面
没有这样的成员,虽然它在实际上是一个子类的对象,这时候,
强制类型转化,当子类用(实际在内存就是,当然安全)

 

C#事件处理程序的写法

 

C#事件处理程序的写法

事件为空的情况

原则:

1、如果没有为事件写好事件处理程序,那么事件(也是个类,类对象)为空

 

C#事件处理程序的写法

 

2、前面所述的

事件+=委托(事件处理程序)

这种语法格式的语句,只是把事件和事件处理程序关联了起来,并且在这个时候,事件处理程序已经是肯定定义了,因为传入了事件处理程序的称,也就是说指明了事件发生时用哪个函数,这同时说明,这种关联是写在事件接收器的(一般用户编写代码都是在事件接收器,比如系统事件都是由系统发出的,在接收方关联到自定义的事件处理程序来实现各种功能应用);

 

事件的引发是在事件发送器端,一般用以下代码实现

 

if(eventObject != null)

{

    eventObject(sender, ev);

}

 

在定义了事件处理程序的时候,eventObject就不是null了,这时候,用eventObject(sender, ev);语句引发事件,相当于C中的sendmessage作用