基于C#规范,10.13 Destructors
“当一个实例被破坏时,析构函数 在该实例的继承链中按顺序被调用,从大多数派生到最少派生。“
我的问题是:
为什么析构函数按顺序被调用,从大多数派生到最少派生? 为什么不按顺序调用,从最少派生到大多数派生或其他顺序?
答案 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
通常是处理对象的受控清理的更好选择。)