我找不到对它的引用,但我记得读过,在析构函数中调用虚拟(多态)方法或IDisposable的Dispose()方法不是一个好主意。
这是真的吗?如果可以,有人可以解释为什么吗?
最佳答案
出于相同的原因,从finalizer / 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();
}
}
这是当您处理和释放类型为
D
的对象d
时发生的情况:((IDisposable)d).Dispose()
C.IDisposable.Dispose()
调用虚拟方法D.Dispose(bool)
D.Dispose(bool)
处理D.X
D.Dispose(bool)
静态调用C.Dispose(bool)
(在编译时已知调用的目标)C.Dispose(bool)
调用虚拟方法D.DoSomething()
D.DoSomething
在已处置的D.X.Whatever()
上调用D.X
方法现在,大多数运行此代码的人都会做一件事来修复它-在清理自己的对象之前,他们将
base.Dispose(dispose)
调用移至。而且,是的,确实有效。但是,您是否真的信任程序员X,您开发C
的公司的特级开发人员,分配给它编写D
,以一种可以检测到错误的方式编写base.Dispose(disposing)
,或者将C
调用在正确的位置?我并不是说您永远都不要永远编写调用Dispose中的虚拟方法的代码,只是您需要文档要求虚拟方法永远不要使用在ojit_code下衍生的任何类中定义的任何状态。
关于.net - 可以从Dispose或析构函数调用虚拟方法吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/137621/