你需要在每个实现中使用
IDisposable
,但这并不一定需要在每个代码中显式实现。让继承为你完成工作。
两种方法:
class FileHandlingClass : IDisposable
{
private FileStream _stm;
public void Disposable()
{
_stm.Dispose();
}
}
class TextHandlingClass : FileHandlingClass
{
}
现在我们可以做到:
using(TextHandlingClass thc = new TextHandlingClass())
thc.DoStuff();
等等。
这一切都能够正常工作,是因为TextHandlingClass
继承了它所需要的唯一一个IDisposable
实现。
如果我们需要进一步释放资源,情况就会变得更加复杂:
假设我们有一个处理池化XmlNameTable
对象的类(为什么这是个好主意是另一个话题),并且将其释放后返回表到池中,而它被XmlHandlingClass
使用。现在,我们可以通过以下方式来处理:
class XmlHandlingClass : FileHandlingClass, IDisposable
{
PooledNameTable _table;
public new void Dispose()
{
_table.Dispose();
base.Dispose();
}
}
现在,这在以下方面表现得很出色:
using(XmlHandlingClass x = new XmlHandlingClass())
x.Blah();
但不包括:
using(FileHandlingClass x = new XmlHandlingClass())
x.Blah()
在后一种情况下,只使用
FileHandlingClass
实现(幸运的是,不将池化名称表返回到池中并不重要,大多数
Dispose()
的情况更为关键)。因此,如果需要覆盖,我们应该这样做:
class FileHandlingClass : IDisposable
{
private FileStream _stm;
public virtual void Disposable()
{
_stm.Dispose();
}
}
class TextHandlingClass : FileHandlingClass
{
}
class XmlHandlingClass : FileHandlingClass
{
PooledNameTable _table;
public override void Dispose()
{
_table.Dispose();
base.Dispose();
}
}
现在我们在调用Dispose()
时更加安全,但仍然只需要在必要的情况下自己实现它。
在第二种情况下会有一点性能损失,但真的很小。我现在指出这一点只是为了反对在需要覆盖Dispose()
的情况下考虑第一种情况。