扩展我的 cmets here,BinaryReader 类没有正确实现 Dispose 模式。
在 Reflector 中查看这个类,它看起来像这样(对于 .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() 成为显式接口实现,它会强制开发人员调用Close() 而不是Dispose()。
在这种情况下,我们遇到了语义不平衡的情况。从来没有调用“打开”阅读器,因此“关闭”阅读器并不直观。
更进一步,为了调用 Dispose(),您必须显式转换为 IDisposable,这不是您通常需要做的事情。你可以选择直接调用Dispose(bool),但是你怎么知道布尔参数应该是什么?
为了正确地遵循模式,它应该被实现为:
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(...))
{
}