【问题标题】:Can Virtual Event Handlers Cause Any Problems虚拟事件处理程序会导致任何问题吗
【发布时间】:2012-11-20 23:14:14
【问题描述】:

将虚拟方法注册为事件处理程序,而不是注册一个委托给虚拟方法的私有方法,是否有任何问题?我更喜欢选项 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)
    {
    }
}

【问题讨论】:

    标签: c# .net events delegates virtual


    【解决方案1】:

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

    第二个选项基本上愚弄了 ReSharper 之类的重构助手,因此他们不会将“构造函数中的虚拟调用”标记为问题;构造函数中的调用不是虚拟的,除非它足够聪明,可以追踪(大多数都不是),否则它不会对级联的虚拟事件视而不见。但是,如果事件(其中一个)是从构造函数中引发的,仍然会有问题。

    除此之外,我不知道有什么问题。

    【讨论】:

    • 关于可能从构造函数调用虚方法的要点是,但这两个选项最终都有可能调用虚方法。
    • +1 用于解释虚拟方法的自上而下执行及其对状态数据的依赖性。
    猜你喜欢
    • 2012-11-02
    • 2021-01-21
    • 2011-05-16
    • 1970-01-01
    • 2013-04-04
    • 2010-09-06
    • 2011-04-01
    • 2018-09-28
    相关资源
    最近更新 更多