我在MSDN文档中遇到了以下示例代码,演示了如何使用System.IO.StreamReader
类从System.IO.FileStream
对象读取UTF-8文本。两个嵌套的using
语句让我感到多余 - 确实在其中一个对象上调用Dispose()
就可以了,并正确释放文件句柄? (来源:http://msdn.microsoft.com/en-us/library/yhfzs7at.aspx)
using (FileStream fs = new FileStream(path, FileMode.Open))
{
using (StreamReader sr = new StreamReader(fs))
{
while (sr.Peek() >= 0)
{
Console.WriteLine(sr.ReadLine());
}
}
}
以下列方式重写代码会不会更简单,同样正确吗?
using (FileStream fs = new FileStream(path, FileMode.Open))
{
StreamReader sr = new StreamReader(fs);
while (sr.Peek() >= 0)
{
Console.WriteLine(sr.ReadLine());
}
}
答案 0 :(得分:2)
根据文件,The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called。这意味着using
StreamReader
保证了对基础Stream
的处置。反之亦然:仅处理Stream
不足就足够了 - StreamReader
可能正在分配其他本机资源。所以第二个样本不正确。
(using
只有StreamReader
不包含StreamReader
构造函数可以抛出的情况。为了涵盖这种情况,需要using
两个。它仅针对不可读或null
流抛出,但这可能不相关。)
一般情况下,您应该始终处理每个一次性物品。它是IDisposable
契约的一部分,它不会多次处理一个对象,并且这样做的开销很低。
答案 1 :(得分:2)
第二个样本原则上是错误的。
它不会泄漏任何东西,但依赖于StreamReader没有自己的资源并且实际上不需要Disposing的知识,即使它是IDisposable。
using(){}
周围的单个StreamReader
在此处或多或少是正确的,基于Reader将关闭其Stream的已记录(并且受到批评)的功能。
这里的最佳做法是使用2个使用语句。请注意,它们非常便宜,您只需要一致的代码。