16.6 使用和扩展EventArgs类

关于EventArgs类,前文已有描述,它位于System命名空间,是预定义委托EventHandler的第二个参数,本身不能包含事件数据。因此,在事件引发时不能向事件处理程序传递状态信息,如果要想传递状态信息,则需要从此类派生出一个类来保存信息,本节的示例还是基于代码清单16-1,并做相应扩展,使得在事件触发后可以传递状态信息到事件处理的代码,因此需要从EventArgs类派生一个新类:PrintEventArgs,其代码如代码清单16-4所示。

代码清单16-4 扩展EventArgs类


1 public class PrintEventArgs:EventArgs

2{

3 public string PrintState

4{

5 get;

6 set;

7}

8

9 public PrintEventArgs(string state)

10{

11 PrintState=state;

12}

13}


上述代码只是扩展EventArgs类的方式之一,这里使用了一个属性来保存状态信息。根据需要可以使用更多的属性,或者使用枚举变量来保存状态信息。

然后,将Printer类ShowMessage方法的第二个参数换成PrintEventArgs类型,如下所示:


public void ShowMessage(object sender,PrintEventArgs e)

{

Console.WriteLine(“打印已完成……”);

}


修改完毕后进行编译,发现在事件绑定的代码部分出现了编译错误:


eventSample.PrintComplete+=ShowMessage;


错误信息为:


"ShowMessage"的重载均与委托"System.EventHandler"不匹配


从错误信息来看,是因为ShowMessage方法和System.EventHandler委托签名不匹配,那么就来观察下两者的签名:

❑System.EventHandler委托:public delegate void EventHandler(Object sender,EventArgs e);

❑ShowMessage方法:public void ShowMessage(object sender,PrintEventArgs e)

通过对比可以发现如下问题:

❑两者的签名不同,System.EventHandler委托的第二个参数是EventArgs,ShowMessage方法的第二个参数为PrintEventArgs。

❑看到签名不同,而且是参数的类型不同,我们就会想到,它是否满足逆变的条件呢?先看看什么是逆变——委托签名中的参数类型继承自委托方法的参数类型,这里的情况是委托方法的参数类型继承自委托签名中的参数类型,恰恰相反,因此不满足逆变的条件,如图16-6所示。

16.6 使用和扩展EventArgs类 - 图1

图 16-6 使用PrintEventArgs作为第二个参数的方法和EventHandler委托不再匹配