虚拟事件处理程序可以导致任何问题

时间:2012-11-20 23:14:14

标签: c# .net events delegates virtual

是否存在将虚拟方法注册为事件处理程序而不是注册委托给虚拟方法的私有方法的问题?我更喜欢选项1(这似乎有效),但我想确保它不会在以后咬我。

选项1

public class Controller1
{
    public Controller1(EventNotifier eventNotifier)
    {
        eventNotifier.ImportantEvent += OnEventNotifierImportantEvent;
    }

    protected virtual void OnEventNotifierImportantEvent(object sender, EventArgs e)
    {
    }
}

选项2

public class Controller2
{
    public Controller2(EventNotifier eventNotifier)
    {
        eventNotifier.ImportantEvent += eventNotifier_OnImportantEvent;
    }

    private void eventNotifier_OnImportantEvent(object sender, EventArgs eventArgs)
    {
        OnEventNotifierImportantEvent(sender, eventArgs);
    }

    protected virtual void OnEventNotifierImportantEvent(object sender, EventArgs e)
    {
    }
}

1 个答案:

答案 0 :(得分:4)

只是不要在构造函数中引发事件。这适用于在构造函数中调用任何虚方法,而不仅仅是引发事件。原因是对象被实例化,构造函数以自上而下的方式执行,而虚拟方法基本上是自下而上解决的。虽然很容易找到虚方法的代码,但如果在构造函数中调用它,则派生的实现可能依赖于尚不存在的状态数据,因为该对象尚未完全实例化。

第二个选项基本上愚弄了像ReSharper这样的重构助手,因此他们不会将“构造函数中的虚拟调用”标记为问题;构造函数中的调用不是虚拟的,除非它足够聪明地跟踪(大多数不是),否则它不会注意级联虚拟事件。但是,如果事件(任何一个)是从构造函数中引发的,那么仍然会有问题。

除此之外,没有我知道的问题。