![](/img/trans.png)
[英]While disposing the class instance, do i need to dispose all its IDisposable members explicitly?
[英]Do i need to Dispose Stream when i Pass it to IDisposable class?
我写了一段代码。 我想确保我正确地处理对象。
我有一个像这样的Disposable类,它用于从非托管资源中读取一些数据。
class MyFileReader : IDisposable
{
private readonly FileStream _stream;
public MyFileReader(FileStream stream)
{
_stream = stream;
}
public void Dispose()
{
_stream.Dispose();
}
}
目前在我的程序中我处理这样的对象。
using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (MyFileReader reader = new MyFileReader(stream))
{
//...
}
}
这对我来说似乎没问题。 后来我注意到Classes是通过引用传递的,所以如果我处理其中一个,就没有必要处理另一个了。
我的问题是我能做这样的事吗?
using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
MyFileReader reader = new MyFileReader(stream);
// Remove IDisposable from MyFileReader and stream will close after using.
}
还是这一个?
FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
// stream will close after using.
using (MyFileReader reader = new MyFileReader(stream))
{
//...
}
是的,你可以编写这样的代码。
但是,不,你不应该这样做。
您的类看起来像XxxxReader类,按惯例拥有它们读取的流。 结果,您的MyFileReader
类应该处理内部流。 当你知道这个物体的寿命结束时,你通常也会期望处理每一个一次性物品。
请注意,有时它会导致对某些对象进行多次Dispose
调用(这应该是IDisposable
的实现所期望的)。 虽然它有时会导致代码分析警告,但如果通过跳过一些常规尝试“优化”调用Dispose
的次数,则优于丢失Dispose调用。
另一种方法是公开读取内容的方法,按照惯例,预期不会取得流/读者的所有权,如:
using(stream....)
{
var result = MyFileReader.ReadFrom(stream);
}
如果MyFileReader正在访问某些非托管资源,并且您需要在此代码块之后显式调用Disponse方法,那么您必须坚持使用当前的实现。
在第二个实现中,不会为MyFileReader对象调用Dispose方法。 (直到你可能在析构函数中调用它,你不知道什么时候会被调用)
如果您不喜欢嵌套使用,那么您可以使用第二种替代方法并在MyFileReader类的Dispose()方法实现中,显式地处理Stream。 如果此流仅由MyFileReader使用,那么让MyFileReader管理其生命周期并对其进行处理是一个很好的做法。
许多框架流包装类具有构造函数重载,其中leaveOpen
参数控制流处理行为。
示例包括StreamReader
, BinaryReader
, GZipStream
。
还有属性方法,SharpZipLib示例:
using (var zip = new ZipInputStream(stream) { IsStreamOwner = false }) { ... }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.