【问题标题】:C# - nested using statements redundant?C# - 嵌套使用语句冗余?
【发布时间】:2014-09-13 19:53:15
【问题描述】:

我在 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());
    }
}

【问题讨论】:

标签: c# filestream dispose streamreader using


【解决方案1】:

根据文档,The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called。这意味着usingStreamReader 保证了底层Stream 的处置。反之亦然:仅处理 Stream 就足够了 - StreamReader 可能正在分配其他本地资源。所以第二个样本不正确。

(using 只有StreamReader 没有涵盖StreamReader 构造函数可以抛出的情况。要涵盖这种情况,两个using 都需要。因为它只抛出不可读或null 流,但这可能无关紧要。)

一般来说,您应该始终丢弃每个一次性物品。这是IDisposable 合约的一部分,多次处理一个对象并没有什么坏处,而且这样做的开销很低。

【讨论】:

  • 您的报价是正确的,但与第二个代码示例无关。
  • @HenkHolterman 我还说第二个样本正是出于这个原因不正确。
【解决方案2】:

第二个样本在原则上是完全错误的。

它不会泄漏任何东西,但这取决于 StreamReader 没有自己的资源并且实际上不需要 Disposing,即使它是 IDisposable。

StreamReader 周围的单个 using(){} 在这里或多或少是正确的,基于 Reader 将关闭其 Stream 的记录(和批评)功能。

这里的最佳做法是使用 2 using statments。请注意,它们非常便宜,您只需要一致的代码。

【讨论】:

  • 请注意,StreamReader 还提供了一个选项来表示不要关闭底层流。同样,仅在 StreamReader 中的单个 using 语句在其构造函数抛出时是一个问题,FileStream 不会被关闭。
  • @SriramSakthivel - 从 Fx 4.5 开始,是的。但这不是这里使用的 cotor。
  • 没错,我补充说有一个选项可以让流保持打开状态。顺便说一句,我编辑了我之前的评论,指出围绕 StreamReader 的单个 using 语句将是危险的。
  • 关于 throwing 的那个论点非常笼统,不适用于这个代码片段。在这种情况下,我不鼓励单独使用但也不挑剔它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 2013-10-13
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多