如果可处置性是基类契约的一部分,为什么不明确说明呢?
abstract class MyBase : IDisposable
{
//some base code here
//an abstract "implementation" of the interface
public abstract void Dispose();
}
这样,您可以确定它的所有后代实际上都是一次性的。您还可以按照以下方式创建集合类而不是通用列表:
class MyBaseCollection : IEnumerable<MyBase>
{
private List<MyBase> innerCollection;
....
public void DisposeItems()
{
// call Dispose on each item here
}
}
正确处理非托管资源可能非常棘手,并且众所周知难以调试。在具体类上实现 IDisposable 接口时,您应该遵循Dispose 模式。
在抽象类本身中,您可以根据要对类层次结构执行的操作来做几件事。
如果所有(或大多数)后代都需要处理逻辑,您可以强制他们使用以下方法实现 Dispose 模式的两种方法:
public abstract void Dispose();
public abstract void Dispose(bool disposing);
这样子孙就别无选择,只能实现方法,否则代码无法编译。
如果大多数类不需要处理,但其中一些仍然需要处理,我会在基类中声明虚拟方法:
public virtual void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing){}
这个默认实现对于大多数后代来说已经足够好了,那些确实需要处理的人可以随意覆盖它。
此外,由于Dispose()
方法的代码几乎总是相同的,您可以实现一个,而将另一个保留为虚拟甚至抽象。
//should not be overridden
public virtual void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
//must be overriden
public abstract void Dispose(bool disposing);