在C#中重写事件真的是错误吗?

在C#中重写事件真的是错误吗?,c#,wpf,.net-3.5,coding-style,event-handling,C#,Wpf,.net 3.5,Coding Style,Event Handling,我在这个问题上读到: 在C#中重写事件甚至是一个错误。《C#编程指南》说: 不要在基类中声明虚拟事件,并在派生类中重写它们。C#编译器在Microsoft Visual Studio 2008中无法正确处理这些问题,并且无法预测派生事件的订阅方是否实际订阅基类事件。 我想知道为什么一个框架类会违反这个规则,甚至为什么编译器会允许它 我不明白为什么忽略事件是错误的。确保继承类始终可以监视基类事件并在之后执行自己的操作,但如果它希望确保它是第一个看到事件的事件观察者,该怎么办?它想在某些条件下决定吞

我在这个问题上读到:

在C#中重写事件甚至是一个错误。《C#编程指南》说: 不要在基类中声明虚拟事件,并在派生类中重写它们。C#编译器在Microsoft Visual Studio 2008中无法正确处理这些问题,并且无法预测派生事件的订阅方是否实际订阅基类事件。 我想知道为什么一个框架类会违反这个规则,甚至为什么编译器会允许它

我不明白为什么忽略事件是错误的。确保继承类始终可以监视基类事件并在之后执行自己的操作,但如果它希望确保它是第一个看到事件的事件观察者,该怎么办?它想在某些条件下决定吞并这一事件?这样做有什么不对:

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        VerifyActiveCountMatches();
        base.OnCollectionChanged(e);
        InvokePropertyChanged("Count");
    }
这样做不是一个错误,但很可能是一个糟糕的设计决策。这有很大的区别;编译器不会让你逃脱错误,但它很少批评你的设计

为集合更改显示的代码不会覆盖事件-它会覆盖引发事件的方法。那是完全不同的事情。事件类似于:

// "Field-like" event - the compiler implements the add/remove and
// creates a backing field.
public event EventHandler Click;
public override event EventHandler CollectionChanged;


这些是处理订阅和取消订阅的代码片段——建议中说您不应该覆盖这些代码。您很少希望这样做,正如引用的文本所说,在很多情况下,它无论如何都不会做您希望它做的事情。

如果不重写事件,您将重写那里的事件调用程序(可能是一个处理程序,但该模式通常表示用于调用事件处理程序的受保护成员)

覆盖一个事件看起来像:

// "Field-like" event - the compiler implements the add/remove and
// creates a backing field.
public event EventHandler Click;
public override event EventHandler CollectionChanged;
我引用博客:

“没有必要在父类中使用类似于虚拟字段的事件,并且不更改其在重写派生类中的任何行为。只需忽略派生类中的重写即可获得所需的行为。”


如果你不改变行为,那为什么要把它虚拟化呢?正如所指出的,这与重写引发事件的方法不同。

同样,重写事件调用程序有什么问题吗?没有,只要记得调用基成员(否则它可能不会被调用)。