关于在单个'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是否会在块的末尾被处理掉。任何解释为什么或为什么不被理解。
答案 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)
简单的答案是否定的 - 你需要包装每个对象。