.NET事件传递的实现与事件链问题

本文探讨了.NET中事件绑定的实现,包括在非构造函数和构造函数中的不同方式,以及构造函数中可能出现的问题及其解决方案。同时,文章还深入讨论了事件链问题,特别是涉及容器类事件链的事件访问器+=重载实现。
(原创文章,转载请注明来源:http://blog.csdn.net/hulihui)

在.NET程序设计时,常常将一些辅助类的事件封装绑定到一个容器类(下面假定为ClassA类)中。于是,经常碰到所谓事件传递或转移问题:辅助类ClassB的事件不直接对客户,而是通过其容器类ClassA发布。下面探讨实现中的两个问题:
  • 事件绑定实现:非构造函数与构造函数中实现的区别
  • 容器类事件链:事件访问器+=重载时添加事件链表

1、事件绑定实现

1)非构造函数中实现

如果与ClassB的事件委托相同,ClassA可以直接+=绑定ClassB的事件,然后传递发布出去,见如下代码:
public class ClassB  // 类 ClassB 通过容器类 ClassA 发布事件
{
public event EventHandler ClassBEvent;
public void Fire()
{
     if (ClassBEvent != null)
{
ClassBEvent(this, new EventArgs());
}
}
}
public class ClassA  // 容器类, 传递发布 ClassB 的事件
{
    public event EventHandler ClassAEvent;
private ClassB classB;

    public ClassA(){}

public void Fire() // 非构造函数
{
classB = new ClassB();
classB.ClassBEvent += this.ClassAEvent; // 绑定 ClassB 的事件给 ClassA
classB.Fire();
}
}

2)构造函数中实现存在的问题

如果在ClassA的构造函数中绑定事件,由于类对象没有完成构建,对象仍然是null,此时绑定事件将存在问题。参考如下ClassA代码:
public class ClassA
{
public event EventHandler ClassAEvent;
private ClassB classB;

public ClassA() // 在构造函数中绑定事件
{
classB = new ClassB();
classB.ClassBEvent += new EventHandler(ClassAEvent); // 类对象仍然是null
}

public void Fire()
{
classB.Fire();
}
}

上述代码运行时将抛出异常信息“未处理的异常: System.ArgumentException: 实例方法的委托不能具有空this。”显然,该信息表明当前类对象仍然是null(即this是null),不能作为创建委托对象的参数。

特别注意:如果采用所谓委托推断方式,即不用 new EventHandler() 建立委托对象,而是直接绑定事件:
    classB.ClassBEvent += this.ClassAEvent;  // 委托推断方式
此时,既不会抛出异常,也不会调用(响应)ClassA的事件注册方法,也就是说上述方法失效了!

3) 构造函数中实现的解决方法

如果要在ClassA的构造函数中绑定事件,则可以写一个符合事件委托的方法,然后+=该方法即可,代码如下:
    public ClassA()  // ClassA 的构造函数
{
classB = new ClassB();
classB.ClassBEvent += OnClassAEvent; // 绑定到一个方法
}

private void OnClassAEvent(object sender, EventArgs e) // 符合委托的方法
{
if (this.ClassAEvent != null)
{
this.ClassAEvent(sender, e);
}
}

2、事件链问题

绑定事件一般使用重载运算符+=,常见情况是添加单个方法。由于事件(或委托)支持链表,那么下面代码:
    classB += ClassAEvent
是添加一个方法还是添加一个事件链?测试表明,+=添加的是注册在ClassA对象上的事件方法链。笔者估计,.NET在事件访问器Add方法重载时考虑到了这种链表添加情况。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值