为什么在该实例的继承链中的析构函数按顺序被调用,从大多数派生到最少派生?

时间:2012-09-29 07:31:15

标签: c#

基于C#规范,10.13 Destructors

  

“当一个实例被破坏时,析构函数   在该实例的继承链中按顺序被调用,从大多数派生到最少派生。“

我的问题是:

为什么析构函数按顺序被调用,从大多数派生到最少派生? 为什么不按顺序调用,从最少派生到大多数派生或其他顺序?

2 个答案:

答案 0 :(得分:6)

据推测,这是因为派生类具有基类成员的知识,并且可能需要在析构函数中使用它们。如果首先调用基础构造函数,则成员可能不可用,否则基础析构函数可能会将对象的状态置于无效状态。

基类当然不知道或无法访问其派生类的成员,因此通过首先调用派生的析构函数来避免这个问题。

答案 1 :(得分:4)

因为对象是从最少派生到最派生的对象构建的,所以它们必须从最派生到最终派生中被拆除。

派生类知道基类,但基类不知道派生类。如果您将对象从最小派生类拆除到最派生类,则基类将删除派生类在该过程中可能需要的内容。

例如,考虑基类有一个对象列表:

public class MyBase {

  public List<SomeObject> list;

  public MyBase(){
    list = new List<SomeObject>();
    list.Add(new SomeObject());
    list.Add(new SomeObject());
    list.Add(new SomeObject());
  }

  ~MyBase() {
    foreach (SomeObject obj in list) {
      obj.Cleanup();
    }
    list.Clear();
  }

}

派生类为列表中的每个项添加内容:

public class MyDerived : MyBase {

  public MyDerived() {
    foreach (SomeObject obj in list) {
      obj.SomeProperty = new Handler();
    }
  }

  ~MyDerived(){
    foreach (SomeObject obj in list) {
      obj.SomeProperty.Cleanup();
    }
  }

}

当对象被拆除时,派生类需要访问列表才能清理它添加的内容。如果基类首先被破坏,派生类将无法访问列表中的对象。

(但请注意,IDisposable通常是处理对象的受控清理的更好选择。)