基于 C# 规范,10.13 析构函数
“当一个实例被破坏时,该实例的继承链中的析构函数被调用,从最衍生到最小衍生。”
我的问题是:
为什么按从最多派生到最少派生的顺序调用析构函数?为什么不按从最少派生到最多派生或其他顺序的顺序调用?
基于 C# 规范,10.13 析构函数
“当一个实例被破坏时,该实例的继承链中的析构函数被调用,从最衍生到最小衍生。”
我的问题是:
为什么按从最多派生到最少派生的顺序调用析构函数?为什么不按从最少派生到最多派生或其他顺序的顺序调用?
大概是因为派生类知道基类的成员,并且可能需要在析构函数中使用它们。如果首先调用基构造函数,则成员可能不可用,或者对象的状态可能已被基析构函数置于无效状态。
当然,基类不了解或无法访问其派生类的成员,因此可以通过首先调用派生更多的析构函数来避免该问题。
因为对象是从最不派生到最派生的,所以它们必须从最派生到最不派生被拆除。
派生类知道基类,但基类不知道派生类。如果您要将对象从派生最少的类拆解到派生最多的类,则基类将删除派生类在此过程中可能需要的东西。
例如,考虑基类有一个对象列表:
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
通常是处理受控对象清理的更好选择。)