为什么在BinaryReader上调用Dispose()会导致编译错误?
我有以下类,它在内部使用BinaryReader并实现IDisposable。为什么在BinaryReader上调用Dispose()会导致编译错误?
class DisposableClass : IDisposable { private BinaryReader reader; public DisposableClass(Stream stream) { reader = new BinaryReader(stream); } protected virtual void Dispose(bool disposing) { if (disposing) { ((IDisposable)reader).Dispose(); // reader.Dispose();// this won't compile } } public void Dispose() { this.Dispose(true); } }
我已经想通了,我需要投BinaryReader在到IDisposable接口能够调用Dispose它,但我不明白为什么我不能直接调用Dispose()方法,无需铸造到IDisposable?
由于BinaryReader
上的Dispose
方法已被明确实施,所以不起作用。
而不是被隐式地实现,如在:
public void Dispose()
{
}
...它已明确实施,如:
void IDisposable.Dispose()
{
}
...这意味着它只能通过以下方式访问接口IDisposable
。因此,您必须首先将实例投射到IDisposable
。
扩展我的意见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(...))
{
}
其实他们都选择用Close( )而不是Dispose() Dispose已经明确实现。这就是为什么你看不到它。
但是Close与dispose完全相同,这是他们希望使用的方法。反射器给出了关闭方法
public virtual void Close()
{
this.Dispose(true);
}
关闭下面拆卸()被使用,因为它是在一个二进制读取的上下文中,更好的选择的话。
完美的例子说明为什么你不应该偏离标准的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