我发现了以下段落。
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;。然后我吃了鸡脚并推迟了答案。有什么我可以失踪的吗?
答案 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方法中没有做任何有趣的事情。)