【发布时间】:2013-10-18 12:46:27
【问题描述】:
好的,我已经阅读了一些关于 IDisposable 最佳实践的内容,我认为我基本上明白了(最终)。
我的问题与从 IDisposable 基类继承有关。我看到的所有示例都在子类中一遍又一遍地编写相同的代码块,但我没有看到优势。
为什么不简单地将虚拟方法烘焙到基类中,在正确的时间从(私有实现的)IDisposable 例程中调用它,这样子类就不会那么混乱,但仍然有机会做管理他们的资源?
我提议的基类:
public abstract class DreamDisposableBase : IDisposable
{
private bool _disposed = false;
protected virtual void LocalDispose(bool disposing)
{
}
~DreamDisposableBase()
{
// finalizer being called implies two things:
// 1. our dispose wasn't called (because we suppress it therein)
// 2. we don't need to worry about managed resources; they're also subject to finalization
// so....we need to call dispose with false, meaning dispose but only worry about *unmanaged* resources:
dispose(false);
}
void IDisposable.Dispose()
{
dispose(true); // true argument really just means that we're invoking it explicitly
}
private void dispose(bool disposing)
{
if (!_disposed)
{
// give sub-classes their chance to release their resources synchronously
LocalDispose(disposing);
if (disposing)
{
// true path is our cue to release our private heap variables...
}
// do stuff outside of the conditional path which *always* needs to be done - release unmanaged resources
// tell .net framework we're done, don't bother with our finalizer -
GC.SuppressFinalize(this);
// don't come back through here
_disposed = true;
}
}
}
【问题讨论】:
-
处置模式要求您将 Dispose(bool) 方法保护为虚拟的。这样派生类就可以覆盖它并调用基方法。实际上,使用处置模式在 99.9% 的情况下都是错误的,编写析构函数几乎从来都不是正确的做法。框架类有一个,你应该把它留给他们。喜欢 SafeHandle。
-
你并没有改进标准模式,只是让事情变得混乱。例如,您的 SuppressFinalize 位于错误的位置。
-
DRY IDisposable Pattern 的可能重复项
-
一篇对理解 IDisposeable 对象很有帮助的文章(以及为什么“标准模式”实际上不是一个好的模式)阅读Stephen Cleary 撰写的文章“IDisposable: What Your Mother Never Told You About Resource Deallocation”。
标签: c# .net memory-management garbage-collection