这个类使用a StreamWriter并因此实现IDisposable.
public class Foo : IDisposable
{
private StreamWriter _Writer;
public Foo (String path)
{
// here happens something along the lines of:
FileStream fileWrite = File.Open (path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
_Writer = new StreamWriter (fileWrite, new ASCIIEncoding ());
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
~Foo()
{
Dispose (false);
}
protected virtual void Dispose (bool disposing)
{
if (_Disposed) {
return;
}
if (disposing) {
_Writer.Dispose ();
}
_Writer = null;
_Disposed = true;
}
private bool _Disposed;
}
Run Code Online (Sandbox Code Playgroud)
}
当前的实施有什么问题吗?即,我是否必须FileStream手动释放底层?被Dispose(bool)正确写入?
Ant*_*nes 39
如果您的类不直接使用非托管资源,则无需使用此广泛版本的IDisposable实现.
一个简单的
public virtual void Dispose()
{
_Writer.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
就足够了.
如果您的消费者无法处理您的对象,那么它将在没有调用Dispose的情况下正常进行GC,_Writer持有的对象也将是GC并且它将具有终结器,因此它仍然可以正确地清理其非托管资源.
编辑
已经做了由Matt提供的链接和其他人我来,我的答案在这里结束一些研究站.原因如下: -
在可继承类上,一次性实现"模式"(我的意思是受保护的虚拟Dispose(bool),SuppressFinalize等marlarky)背后的前提是子类可能保留非托管资源.
但是在现实世界中,我们绝大多数的.NET开发人员都不会在非托管资源附近.如果你必须量化" 可能 ",那么你会想到什么样的.NET编码?
让我们假设我有一个Person类型(为了论证,在其中一个字段中有一个一次性类型,因此应该是一次性的).现在我有继承者Customer,Employee等.如果有人继承了Person并希望拥有一个非托管资源,那么使用这个"模式"来混淆Person类是否合理?
有时候,我们开发人员可能会过度复杂化,试图对所有可能的情况进行编码,而不会使用关于这种情况的相对概率的常识.
如果我们想要直接使用非托管资源,那么敏感模式就会将这样的东西包装在自己的类中,其中完整的"一次性模式"是合理的.因此,在大量的"正常"代码中,我们不必担心所有这些问题.如果我们需要IDisposable,我们可以使用上面的简单模式,是否可继承.
哎呀,很高兴从胸前把它弄下来.;)
Mat*_*lls 16
您不需要Finalize(析构函数)方法,因为您没有任何非托管对象.但是,如果GC.SuppressFinalize从Foo继承的类具有非托管对象,则应该保持调用,因此终结器.
如果你使类密封,那么你知道非托管对象永远不会进入等式,所以没有必要添加protected virtual Dispose(bool)重载,或者GC.SuppressFinalize.
编辑:
@ AnthonyWJones对此的反对意见是,如果你知道子类不会引用非托管对象,那么整体Dispose(bool)并GC.SuppressFinalize没有必要.但是,如果是这种情况,你应该真正创建类internal而不是public,并且Dispose()方法应该是virtual.如果您知道自己在做什么,那么请不要遵循Microsoft的建议模式,但在破坏规则之前,您应该了解并理解规则!