5

基于 C# 规范,10.13 析构函数

“当一个实例被破坏时,该实例的继承链中的析构函数被调用,从最衍生到最小衍生。”

我的问题是:

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

4

2 回答 2

6

大概是因为派生类知道基类的成员,并且可能需要在析构函数中使用它们。如果首先调用基构造函数,则成员可能不可用,或者对象的状态可能已被基析构函数置于无效状态。

当然,基类不了解或无法访问其派生类的成员,因此可以通过首先调用派生更多的析构函数来避免该问题。

于 2012-09-29T07:32:46.300 回答
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通常是处理受控对象清理的更好选择。)

于 2012-09-29T07:44:18.377 回答