关于.NET框架中继承的一般问题

时间:2010-05-03 03:04:40

标签: c# .net inheritance event-handling

我有一个关于.NET框架中继承的一般问题,假设你有2个类,第一个叫做Parent,第二个叫做Child。孩子继承自父母。

父级希望确保每个子实例在加载时执行特定的代码段,而不管子级是否有明确指定的onLoad代码。

根据我的经验,如果我在父级而不是在子级中处理onLoad,则父级onLoad代码将触发,但如果在两个类中处理它,则仅触发子代码。

这是对的吗?如果是这样,我怎样才能确保父母的代码永远为孩子开火......

5 个答案:

答案 0 :(得分:7)

您发现了fragile base class问题。处理它的一种方法是这种模式:

public class Parent
{
    public void OnLoad()
    {
        // Important load stuff goes here
        OnLoadInternal();
    }

    protected virtual void OnLoadInternal()
    {
        // No implmentation in parent; child can override if needed
    }
}

public class Child : Parent
{
    protected override void OnLoadInternal()
    {
        base.OnLoadInternal();

        // Important load stuff, but can't break parent by omitting base call
    }
}

父母保证让它的OnLoad方法做它应该做的事情,但是孩子可以通过覆盖OnLoadInternal来增加额外的处理。

答案 1 :(得分:2)

在C#中,使用子进程中的base.methodNameHere()来调用父类的方法。

在这种情况下,从您孩子的onLoad()方法中调用base.onLoad()来执行父代码。

答案 2 :(得分:2)

如果在基类的默认构造函数中连接行为,并在私有方法中执行该行为,则子类无法覆盖。您将失去在子类中控制此行为的能力以及各个处理程序执行的时间(以何种顺序)。

public partial class Parent : Form
{
    public Parent()
    {
        InitializeComponent();
        Load += ParentLoad;
    }

    private void ParentLoad(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}

答案 3 :(得分:1)

不要立即调用onLoad(),而是调用私有函数,例如beforeLoad()。这个函数可以完成你想让父母做的所有事情,然后它会调用onLoad(),它可以在Child类中被覆盖。

答案 4 :(得分:1)

.NET SDK中的两个已建立的模式是虚函数和事件。

虚拟功能

class Parent {
  virtual protected void OnLoad() {
    //code here
  } 
}

class Child {
  protected override void OnLoad() {
    base.OnLoad();
  }
}

在这种情况下,您可以为子类提供完全覆盖OnLoad行为的选项,包括不执行基类OnLoad的能力(这可能是完全合法的情况)。

使用活动

或者,您可以使用事件,这是让子类进行附加工作的一种方法,而无需覆盖基类行为:

class Parent {
  public event Load;
  public Parent() {
    this.Load+=OnLoad();
  }
  private void OnLoad() {
    //Parent code here
  } 
}

class Child {
  public Child() {
    this.Load+=OnLoad();
  }
  private void OnLoad() {
    //Child code here
  }
}

这是真正的设计选择。如果您希望框架帮助您强制执行父代码,请转到选项2。