在派生类的构造函数中添加事件处理程序或覆盖OnX()方法?

时间:2010-06-25 18:22:23

标签: c# .net events inheritance

在设计派生类时,在ctor vs中覆盖OnEventName()方法并添加一些行为(以及调用基本方法),如果一个人不需要改变基本方法而不关心事情发生的顺序,但只想要一个具有一点额外行为的可重用组件?

基类:

public abstract class BaseClass
{
    public event EventHandler SomeEvent;
    protected void OnSomeEvent(object sender, EventArgs e)
    {
        // do some stuff
    }
}

选项A:

public class DerivedA
{
    protected override void OnSomeEvent(object sender, EventArgs e)
    {
        // do some other stuff
        base.OnSomeEvent(sender, e);
    }
}

选项B:

public class DerivedB
{
    public DerivedB()
    {
        SomeEvent += (o,e) => { // do some other stuff };
    }
}

2 个答案:

答案 0 :(得分:3)

这两种方法都没有任何重要的优点/缺点。

订阅事件与覆盖基类方法之间存在一些差异。例如,如果您希望在所有其他处理程序之前或之后运行某些代码,则应该覆盖OnSomeEvent方法,因为否则无法对其进行保护。但是你表示你并不关心这一点。

通常,重写方法需要很好地理解基类的行为,以确保您不会无意中破坏任何内容。订阅一个事件是一个不那么具有侵入性的扩展,并且是(大概)基类设计师计划的事情。

有时人们争辩说,当压倒时表现会更好 - 但我不会买这个论点。性能仅在重要时才有意义。这里的差异可能是微不足道的,人们应该更关注简单性,正确性以及易于维护而不是性能。

答案 1 :(得分:2)

您已经提到了调用事物的顺序。其他一些事情肯定不会经常发生,但可能很重要(基于基类控制事件处理程序的调用方式):

  • 可以在不同的线程上调用事件处理程序;
  • 在某些情况下,基类可能会选择不调用事件处理程序;
  • 基类可能会捕获处理程序抛出的特定类型的异常;您的处理程序抛出的异常可能会被无意吞下。

一般情况下,我倾向于将事件视为专门针对某个类用户的事件,并且设计良好的类具有用于子类的虚拟On...方法。