将'IDisposable'嵌套在一个'using'语句中

时间:2016-01-07 20:20:45

标签: c# idisposable using-statement

关于在单个'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 );
}

VS

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语句中,或者它是否保持打开状态,需要在此之后的某个时间进行清理。 / p>

编辑: 为了清楚起见,我不是在讨论使用语句进行嵌套。我问的是,在另一个IDisposable的'using'语句中创建的IDisposable是否会在块的末尾被处理掉。任何解释为什么或为什么不被理解。

3 个答案:

答案 0 :(得分:6)

这取决于构造函数,GZipStream处理您在处理它时传入的流,除非您使用其中一个接收bool的overloads并传入{{1} } true

但是你这样做会冒风险。如果leaveOpen抛出GZipStream,因为流的ArgumentException属性为CanRead,则传入的流不会被丢弃。

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

  

编辑:为了清楚起见,我不是在讨论使用语句进行嵌套。   我在问是否在内部创建了IDisposable   另一个IDisposable的'使用'声明将在最后处理   块。任何解释为什么或为什么不被理解。

如果这是你的问题,那么答案是:不,只会处理声明分配给(false)的对象,创建的任何其他对象都依赖于任何“外部”对象的代码将被实现为“链接调用”using var whatever = ...方法。

答案 1 :(得分:3)

  

如果块执行完毕,则来自" myFile.txt"的未命名FileStream得到清理,因为它在使用GZipStream的

的using语句中

即使两个构造者都成功了,它仍然取决于拥有者的设计。类。 StreamReader将关闭其BaseStream,但许多其他类不会被激活。

您不希望您的代码依赖于这种模糊不清且易于更改的细节。

答案 2 :(得分:2)

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