是否正在使用防范所有可能性?

时间:2014-11-19 17:13:30

标签: c# using

我发现了以下段落。

using (TextWriter w1 = new StringWriter(...))
using (XmlWriter w2 = new XmlTextWriter(w1))
using (StringReader r1 = new StringReader(...))
using (XmlTextReader r2 = new XmlTextReader(r1))
{
  _xslt.Transform(r2, w2);
  ...
  FileOperations.LockFiles();

  w1.Close();
  w2.Close();
  r1.Close();
  r2.Close();
}

我的建议是(除了重命名之外)我们可以删除最后四个语句,因为这些语句是使用使用声明的,并且在框架感觉时会被关闭并正确处理。< / p>

然而,其中一位开发人员质疑我,并提出了一个非常令人不安的问题。 &#34; 完全确定吗?&#34;。然后我吃了鸡脚并推迟了答案。有什么我可以失踪的吗?

3 个答案:

答案 0 :(得分:3)

是的,using块将始终处置对象,无论如何。 (好吧,没有像停电这样的事件......)

此外,处理对象是非常可预测的,总是发生在using块的末尾。 (一旦对象被丢弃,它们就会从终结器队列中删除,并且只是可以被垃圾收集的常规托管对象,这在垃圾收集器发现方便时会发生。)

相反,只有在块内没有未处理的异常时才会调用Close调用。如果您希望它们确实被执行,您可以将它们放在finally块中,以便即使存在异常也可以执行它们。 (这就是using块用于确保它们始终可以处置对象的内容。)

答案 1 :(得分:2)

在很多情况下,using不会处置有问题的资源。例如,如果您在using运行时拔出计算机上的插件,finally块(using转换为)将无法运行。

不存在finally块无法运行的情况,其中重复using内的相同清理步骤将更适合处理。

答案 2 :(得分:1)

如果这样的争议出现了,只需启动ILSpy(http://ilspy.net/)并查看框架,看看它在从使用语句结束时调用的Dispose上实际做了什么。

在这种情况下,你是对的,所有四个StringWriter,StringReader,XmlTextReader和XmlTextWriter都在Dispose方法中处理它们,而Close只调用Dispose,所以这四行是多余的。 (但请注意,StringWriter和StringReader似乎在他们的Dispose方法中没有做任何有趣的事情。)