在C#语句之外声明using语句的目标对象

时间:2014-12-21 18:18:17

标签: c# using-statement

问题:在using语句中声明using语句的目标对象是否有优势,如下面的“代码片段1”中所示?

'代码段2'和'代码段3'片段对我来说似乎也有效,但不确定第一个代码段是否比其他两个代码段有一些好处。

代码段1

 using (TextWriter w = File.CreateText("log.txt")) {
     w.WriteLine("This is line one");
     w.WriteLine("This is line two");
  }

代码段2

 TextWrite w = null;
 using (w = File.CreateText("log.txt")) {
     w.WriteLine("This is line one");
     w.WriteLine("This is line two");
  }

代码段3

 TextWriter w = File.CreateText("log.txt");
 using (w) {
     w.WriteLine("This is line one");
     w.WriteLine("This is line two");
  }

更新1:当实例化TextWriter对象时,在第一行发生异常时,“代码片段3”似乎可能最终没有处理资源。因此,前两个片段在处理资源时看起来是等效的,而第三个片段绝对不建议使用,除非第三个片段有一个最终块,TextWriter对象将被释放。

更新2:在得到彼得的答案后,我意识到我在UPDATE 1中的观察结果不正确。解释如下:如果在3个片段中的任何一个片段中实例化TextWriter时发生异常,则Dispose方法将永远不会被调用,因为没有TextWriter对象来调用此方法。

2 个答案:

答案 0 :(得分:2)

唯一的潜在好处是声明变量的可见性降低(因为它只在using块中可见)和可读性。

答案 1 :(得分:2)

您的示例#2和#3是等效的,与您在" UPDATE 1 "中的假设相反。如果File.CreateText()方法调用中发生异常,则不返回任何对象并将其分配给w。因此,无论您是在using语句之前还是作为其一部分进行分配,如果成功创建了对象,它将根据需要成功清除。

也就是说,示例#1至少有两个的原因:

  1. 正如在另一个答案中所提到的,它减少了变量的范围,因此它只能在using语句块中访问。由于同样的原因,范围变量在任何情况下都很有用,这很有用。
  2. 另一个好处(和IMHO最重要的一个)是作为using语句的一部分声明的变量是只读的。这可以确保您不会意外地编写试图在可清理之前切换一次性对象的代码,即创建一个模糊的情况,其中只有一个一次性对象被using语句清理掉。