我找不到它的引用,但我记得读过在析构函数或IDisposable的Dispose()方法中调用虚拟(多态)方法不是一个好主意.
这是真的,如果是这样,有人可以解释为什么吗?
从终结器调用虚拟方法/ Dispose是不安全的,出于同样的原因,在构造函数中进行操作是不安全的.无法确定派生类是否还没有清除虚拟方法正确执行所需的某些状态.
有些人对标准的Disposable模式以及它对虚拟方法的使用感到困惑virtual Dispose(bool disposing),并且认为这样可以在处理中使用任何虚拟方法.请考虑以下代码:
class C : IDisposable {
private IDisposable.Dispose() {
this.Dispose(true);
}
protected virtual Dispose(bool disposing) {
this.DoSomething();
}
protected virtual void DoSomething() { }
}
class D : C {
IDisposable X;
protected override Dispose(bool disposing) {
X.Dispose();
base.Dispose(disposing);
}
protected override void DoSomething() {
X.Whatever();
}
}
Run Code Online (Sandbox Code Playgroud)
这是Dispose和类型对象时发生的事情D,称为d:
((IDisposable)d).Dispose()C.IDisposable.Dispose() 调用虚方法 D.Dispose(bool)D.Dispose(bool) 处置 D.XD.Dispose(bool)C.Dispose(bool) 静态调用(调用目标在编译时已知)C.Dispose(bool) 调用虚方法 D.DoSomething()D.DoSomething调用D.X.Whatever()已经处理好的方法D.X现在,大多数运行此代码的人都会做一件事来修复它 - 他们base.Dispose(dispose)在清理自己的对象之前将调用移动.而且,是的,这确实有效.但是你真的相信程序员X,你开发的公司的Ultra-Junior开发人员C,被指派编写D,以一种能够检测到错误的方式编写它,或者base.Dispose(disposing)在正确的位置进行调用吗?
我不是说你应该永远,永远编写调用从配置一个虚拟方法的代码,只是你需要记录虚拟方法的要求,它从来没有使用在以下派生的任何类定义的任何状态C.