c# - 虚拟事件处理程序会导致任何问题吗

标签 c# .net events delegates virtual

将虚拟方法注册为事件处理程序与注册委托(delegate)给虚拟方法的私有(private)方法相比是否存在任何陷阱?我更喜欢选项 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)
    {
    }
}

最佳答案

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

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

除此之外,我没有遇到任何问题。

关于c# - 虚拟事件处理程序会导致任何问题吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13483848/

相关文章:

c# - ASP.NET MVC - 找到与 Controller 匹配的多种类型

c# - 什么样的内存语义支配 C# 中的数组赋值?

c# - .net 框架是否支持在不同版本 1.1 和 3.5 之间使用策略文件进行程序集重定向?

wpf - 按键事件 : how to capture down and up key rows?

c# - 查找字符串中出现次数最多的单词 C#

c# - 控件应该在 ViewModel 中吗?

c# - 与 Reactive Extensions 的双向通信

.net - 设置字体真的有多重要?

python - 单击按钮并按回车键时调用相同的函数

linux - 如何在 bash 中获取 MouseMove 和 MouseClick?