【问题标题】:Nesting 'IDisposable's in a single 'using' statement将“IDisposable”嵌套在单个“使用”语句中
【发布时间】:2016-04-12 09:23:36
【问题描述】:

关于在单个“using”语句中使用嵌套一次性用品的快速问题:我应该写出每个一次性用品的 using 语句,还是可以将它们嵌套成一个?示例:

using( FileStream inFile = new FileStream( "myFile.txt", FileMode.Open ) )
using( GZipStream gzip = new GZipStream( inFile, CompressionMode.Decompress ) )
using( FileStream outFile = new FileStream( "myNewFile.txt", FileMode.CreateNew ) )
{
    gzip.CopyTo( outstream );
}

对比

using( GZipStream gzip = new GZipStream( new FileStream( "myFile.txt", FileMode.Open ), CompressionMode.Decompress ) )
using( FileStream outFile = new FileStream( "myNewFile.txt", FileMode.CreateNew ) )
{
    gzip.CopyTo( outstream );
}

只是好奇当块执行完毕后,“myFile.txt”中未命名的 FileStream 是否会被清理,因为它在 GZipStream 的 using 语句中,或者它是否保持打开状态并需要在此之后的某个时间进行清理。

编辑: 为了清楚起见,我不是在问嵌套 using 语句。我在问在另一个 IDisposable 的“使用”语句中创建的 IDisposable 是否会在块的末尾被处理掉。任何关于为什么或为什么不的解释将不胜感激。

【问题讨论】:

  • 如果 FileStream 构造函数成功但 GZipStream 构造函数失败,那么,哎呀。
  • 也许值得设置一组非常简单的实现 IDisposable 的虚拟类并观察调试器中发生的情况?
  • 第二个例子中没有明确处理第一个FileStream对象。当 那个 对象被处置时,它可能GZipStream 对象处置,但是像第一个示例中那样自己显式处置它似乎更合理。
  • 请注意,如果正确实施,Dispose 是幂等的。不小心“双重处置”一个对象绝不是错误的。因此,我可能会犯更多的处置错误,而不是更少。

标签: c# idisposable using-statement


【解决方案1】:

这取决于构造函数,GZipStream 在你处理它时处理你传入的流,除非你使用overloads 之一,它接受一个布尔值并将true 传入leaveOpen

但是,这样做确实有风险。如果GZipStream 抛出ArgumentException,因为流的CanRead 属性是false,传入的流不会被处理掉。

就我个人而言,我宁愿不依赖于“不会出错”,而是通常使用防御性编码并使用 3 语句版本。


编辑:为了清楚起见,我不是在问嵌套 using 语句。 我在问是否在内部创建了 IDisposable 另一个 IDisposable 的 'using' 语句将在最后被处理掉 块的。任何关于为什么或为什么不的解释将不胜感激。

如果这是您的问题,那么答案是:不,只有分配给 (using var whatever = ...) 的声明对象将被释放,创建的任何其他对象都取决于“外部”对象的代码实现“链式调用”Dispose() 方法。

【讨论】:

    【解决方案2】:

    如果块执行完毕,“myFile.txt”中未命名的 FileStream 将被清理,因为它在 GZipStream 的 using 语句中

    即使两个构造函数都成功,它仍然取决于“拥有”类的设计。 StreamReader 将关闭其 BaseStream 但许多其他类不会。

    您不希望您的代码依赖于如此模糊且易于更改的细节。

    【讨论】:

      【解决方案3】:

      简单的答案是否定的 - 您需要包装每个对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多