当我将它传递给 IDisposable 类时是否需要处理流?

M.k*_*ary 5 c# idisposable using

我写了一段代码。我想确保我以正确的方式处理对象。

我有一个像这样的一次性类,用于从非托管资源读取一些数据。

class MyFileReader : IDisposable
{
    private readonly FileStream _stream;

    public MyFileReader(FileStream stream)
    {
        _stream = stream;
    }

    public void Dispose()
    {
        _stream.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

目前在我的程序中,我像这样处理对象。

        using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (MyFileReader reader = new MyFileReader(stream))
            {
                //...
            }
        }
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎没问题。后来我注意到类是通过引用传递的,所以也许如果我处理其中一个,就不需要处理另一个。

我的问题是我可以做这样的事情吗?

        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.
        }
Run Code Online (Sandbox Code Playgroud)

还是这个?

        FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
        // stream will close after using.
        using (MyFileReader reader = new MyFileReader(stream))
        {
            //...
        }
Run Code Online (Sandbox Code Playgroud)

Ale*_*kov 3

是的,您可以编写这样的代码。

但是,不,你不应该这样做。

您的类看起来像 XxxxReader 类中的一个,按照惯例,这些类拥有它们从中读取的流。因此,您的MyFileReader类应该处理内部流。当您知道每个一次性对象的生命周期结束时,您通常还希望处理掉这些对象。

请注意,有时它会导致Dispose对某些对象的多次调用(这应该是 的实现所预期的IDisposable)。虽然有时可能会导致代码分析警告,但如果经常尝试通过跳过某些调用来“优化”调用数量,那么它比错过 Dispose 调用要好Dispose

另一种方法是公开读取内容的方法,按照惯例,预计不会取得流/读取器的所有权,例如:

 using(stream....)
 {
   var result = MyFileReader.ReadFrom(stream);
 }
Run Code Online (Sandbox Code Playgroud)

  • @AmitKumarGhosh你的意思是“有不遵循规则的 IDisposable 实现”?http://stackoverflow.com/questions/5306860/should-idisposable-dispose-be-made-safe-to-call-multiple-times,MSDN:“如果一个对象的 Dispose 方法被调用多次,该对象必须忽略第一个之后的所有调用。如果多次调用该对象的 Dispose 方法,则该对象不得引发异常。” (2认同)