当使用using语句块时,是否必须调用Close方法?

7
using ( var sw = new StreamWriter ( file ) )
{
    XmlSerializer xs = new XmlSerializer ( typeof ( T ) );
    xs.Serialize ( sw, data );
    sw.Close()
}

我知道你不必调用Dispose,但是你是否需要调用sw上的Close方法?


(注:本文涉及IT技术相关内容,建议读者具备一定的专业知识)

2
https://dev59.com/XHM_5IYBdhLWcg3w3nbz - ClosureCowboy
2个回答

11

不需要!你不必这样做。使用“using”即可解决。


1
谢谢,但是它是如何知道调用Close方法的呢?它是由Dispose方法实际调用的吗? - Joan Venge
1
@Joan Venge,反之亦然 - 请参见 ClosureCowboy 链接的已接受答案。using调用IDisposable的Dispose方法,这也是Close所做的。 - Dan J
请查看https://dev59.com/NnNA5IYBdhLWcg3wjOzf#911431 - Bala R
6
无论是Close调用Dispose还是相反都是实现细节。在 StreamWriter 的情况下,确实是Close调用Dispose,但例如在 SqlDataReader 中,Dispose方法调用Close。(当然,无论哪种方式最终结果都是相同的。) - LukeH

2
IDisposable的整个概念是,实现它的类在调用IDisposable.Dispose方法时将执行任何必要的“合理”清理工作。Dispose执行的确切操作可能会因对象状态的不同而异,并且可能不总是所需的清理样式。例如,如果未先调用“提交”方法就处理/事务对象,则该对象可能会在被处理时执行回滚。这将恢复命令/事务到“安全”状态,但不一定是预期的状态。
还要注意,在涉及显式“关闭”,确定性“处理”或非确定性“终结”(由于对象被放弃而导致)的情况下,错误处理可能不同。从语义上讲,明确失败的“关闭”操作应该引发异常,因为关闭的对象没有处于正确的状态。不清楚Dispose方法是否应该这样做(*)。一些类将从失败的处理中抛出异常,而其他类则不会。如果对象被放弃并且在终止期间发生问题,则很少有类会提供任何通知,因为没有良好的机制来处理它。如果在保存文档结束时的“关闭”操作失败,因为某人过早地拔掉了USB驱动器,则应用程序可以通知用户文档可能没有保存,用户可以相应地采取行动。如果应用程序放弃文件对象,因此直到某个时间后才发生“关闭”操作,而此时USB驱动器已被移除,则应用程序实际上无法处理错误。在前一种情况下,程序可以建议用户再次尝试保存文档,但在后一种情况下,文档可能已经丢失。
(*)如果Dispose发生时没有异常挂起,并且Dispose无法执行其所需的清理工作,则很明显应该抛出异常。另一方面,如果已经有异常挂起,从Dispose中抛出将破坏先前异常持有的所有信息。我的首选风格是使用Dispose(Exception Ex)方法,如果Dispose失败,则将Ex作为内部异常传递,但是在vb.net中只能使用笨拙的语法来支持这样的功能,在C#中则具有可疑的行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接