我不喜欢样板代码:复制粘贴重用可能容易出错。即使您使用代码片段或智能模板,也不能保证其他开发人员做到了,这意味着不能保证他们做对了。而且,如果您必须查看代码,则必须理解和/或维护它。
我想从社区知道的是:我对类层次结构的IDispose实现是“传统”处置模式的合法替代方案吗?合法的,我的意思是正确的、性能相当好的、健壮的和可维护的。
我可以接受这种选择是完全错误的,但如果是,我想知道为什么。
此实现假定您可以完全控制类层次结构;如果你不这样做,你可能不得不求助于样板代码。对Add*()的调用通常在构造函数中进行。
public abstract class DisposableObject : IDisposable
{
protected DisposableObject()
{}
protected DisposableObject(Action managedDisposer)
{
AddDisposers(managedDisposer, null);
}
protected DisposableObject(Action managedDisposer, Action unmanagedDisposer)
{
AddDisposers(managedDisposer, unmanagedDisposer);
}
public bool IsDisposed
{
get { return disposeIndex == -1; }
}
public void CheckDisposed()
{
if (IsDisposed)
throw new ObjectDisposedException("This instance is disposed.");
}
protected void AddDisposers(Action managedDisposer, Action unmanagedDisposer)
{
managedDisposers.Add(managedDisposer);
unmanagedDisposers.Add(unmanagedDisposer);
disposeIndex++;
}
protected void AddManagedDisposer(Action managedDisposer)
{
AddDisposers(managedDisposer, null);
}
protected void AddUnmanagedDisposer(Action unmanagedDisposer)
{
AddDisposers(null, unmanagedDisposer);
}
public void Dispose()
{
if (disposeIndex != -1)
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
~DisposableObject()
{
if (disposeIndex != -1)
Dispose(false);
}
private void Dispose(bool disposing)
{
for (; disposeIndex != -1; --disposeIndex)
{
if (disposing)
if (managedDisposers[disposeIndex] != null)
managedDisposers[disposeIndex]();
if (unmanagedDisposers[disposeIndex] != null)
unmanagedDisposers[disposeIndex]();
}
}
private readonly IList<Action> managedDisposers = new List<Action>();
private readonly IList<Action> unmanagedDisposers = new List<Action>();
private int disposeIndex = -1;
}
这是一个“完整”的实现,因为我提供了对终结器的支持(知道大多数实现不需要终结器)、检查对象是否被释放等。真正的实现可能会移除终结器,例如,或创建一个包含终结器的DisposableObject的子类。基本上,我只为这个问题投入了我能想到的一切。
我可能错过了一些边缘情况和深奥的情况,所以我邀请任何人在这种方法中戳漏洞或通过更正来支持它。
其他选择可能是在DisposableObject中使用单个Queue<Disposer> 处理器而不是两个列表;在这种情况下,当调用处理程序时,它们会从列表中删除。我能想到其他一些细微的变化,但它们具有相同的一般结果:没有样板代码。