我曾经很确定答案是“否”,如Overriding the Finalize method和Object.Finalize documentation中所解释的那样。是否允许终结器调用其他托管类的方法?
然而,尽管随机通过FileStream
在反射器浏览,我发现它可以从一个终结实际调用了这样一个方法:
private SafeFileHandle _handle;
~FileStream()
{
if (this._handle != null)
{
this.Dispose(false);
}
}
protected override void Dispose(bool disposing)
{
try
{
...
}
finally
{
if ((this._handle != null) && !this._handle.IsClosed) // <=== HERE
{
this._handle.Dispose(); // <=== AND HERE
}
[...]
}
}
我开始怀疑这是否会一直工作,由于在具体的方式它的写法是否正确,因此,“不要触摸终结者的托管类”只是一条可以被打破的指导方针,只要有充分的理由和必要的知识才能做到这一点。
我挖得更深一点,发现当“规则”被破坏时可能发生的最糟糕的情况是正在访问的托管对象已经完成,或者可能在单独的线程上并行完成。所以如果SafeFileHandle的终结器没有做任何会导致后续调用Dispose失败的事情,那么上面应该没问题吧?
问题:所以可能毕竟是在另一个管理类中的方法可以被称为从终结可靠情况呢?我一直认为这是错误的,但是这个代码表明这是可能的,并且可以有充足的理由来做到这一点。
奖金:观察该SafeFileHandle
甚至不知道它正在从一个终结所谓,因为这只是一个Dispose()
正常通话。基类SafeHandle
实际上有两种私有方法,InternalDispose
和InternalFinalize
,在这种情况下将调用InternalDispose
。这不是问题吗?为什么不呢?...