扩展我的意见here,BinaryReader
类没有正确实施Dispose模式。
望着这个类反射器,它看起来像这样(的.NET 3.5):
public class BinaryReader : IDisposable
{
public virtual void Close()
{
this.Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Stream stream = this.m_stream;
this.m_stream = null;
if (stream != null)
{
stream.Close();
}
}
this.m_stream = null;
this.m_buffer = null;
this.m_decoder = null;
this.m_charBytes = null;
this.m_singleChar = null;
this.m_charBuffer = null;
}
void IDisposable.Dispose()
{
this.Dispose(true);
}
}
这里的问题是,通过使IDisposable.Dispose()
implementaiton它显式接口迫使开发人员调用Close()
代替Dispose()
。
在这种情况下,我们有一个不平衡的语义的情况。从来没有打电话给“打开”阅读器,因此“关闭”阅读器并不直观。
更进一步,为了调用Dispose(),您必须明确地将其转换为IDisposable
,这不是您通常需要做的事情。你可以直接调用Dispose(bool)
,但你怎么知道布尔参数应该是什么?
要正确地遵循的模式,它应该被implmented为:
public class BinaryReader : IDisposable
{
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Stream stream = this.m_stream;
this.m_stream = null;
if (stream != null)
{
stream.Close();
}
}
this.m_stream = null;
this.m_buffer = null;
this.m_decoder = null;
this.m_charBytes = null;
this.m_singleChar = null;
this.m_charBuffer = null;
}
public void Dispose()
{
this.Close();
}
}
这将允许你打电话或者Close()
或Dispose()
,在这种情况下,无论是呼叫继续导致调用Dispose(true)
。 (通过调用Close()
或((IDisposable)reader).Dispose()
,这与实际执行的流程相同)。
幸运的(或不幸的是,这取决于你选择看它哪条路),因为BinaryReader
确实实现了IDisposable
接口,它允许在using语句:
using (BinaryReader reader = new BinaryReader(...))
{
}
完美的例子说明为什么你不应该偏离标准的Dispose模式。 – 2008-10-21 19:01:20
或者只是调用BinaryReader.Close(),它可以做同样的事情。 – 2008-10-21 19:05:50
即便如此,如果你实现了一个Close()方法,它应该完成通常在Dispose()和Dispose()中完成的工作,只需调用Close()即可。无论如何,BinaryReader没有正确地遵循该模式。 – 2008-10-21 19:13:53