C# 使用using作用域时,是否必须调用Close方法?
我知道你不必调用C# 使用using作用域时,是否必须调用Close方法?,c#,.net,dispose,C#,.net,Dispose,我知道你不必调用Dispose,但是你必须调用sw上的Close方法吗?不!你不必这么做。通过“使用”解决了这一问题IDisposable背后的整个思想是,如果调用IDisposable.Dispose方法,实现IDisposable的类将执行“合理”清理所需的任何操作。Dispose执行的确切操作可能因对象的状态而异,并且可能并不总是所需的清理样式。例如,如果命令/事务对象在未首先调用“commit”方法的情况下被释放,那么它可能会执行回滚。这会将命令/事务恢复到“安全”状态,但不一定是预期的
Dispose
,但是你必须调用sw
上的Close
方法吗?不!你不必这么做。通过“使用”解决了这一问题IDisposable背后的整个思想是,如果调用IDisposable.Dispose方法,实现IDisposable的类将执行“合理”清理所需的任何操作。Dispose执行的确切操作可能因对象的状态而异,并且可能并不总是所需的清理样式。例如,如果命令/事务对象在未首先调用“commit”方法的情况下被释放,那么它可能会执行回滚。这会将命令/事务恢复到“安全”状态,但不一定是预期的状态
还请注意,在涉及显式“关闭”、确定性“处置”或非确定性“最终确定”(由于对象被放弃)的情况下,错误处理可能会有所不同。语义上很清楚,如果“close”操作没有导致关闭对象处于正确的状态,则应该抛出异常。Dispose方法是否应该这样做还不太清楚。(*)一些类将从失败的Dispose中抛出,而其他类则不会。如果一个对象被放弃,并且在finalize过程中出现问题,那么很少有类会提供任何通知,因为没有好的机制来处理它。如果保存文档结束时的“关闭”操作因某人过早拔出其USB驱动器而失败,应用程序可以通知用户文档可能未保存,用户可以采取相应的行动。如果应用程序放弃了文件对象,因此“关闭”操作直到一段时间后才发生,此时USB驱动器已被移除,那么应用程序实际上无法处理该错误。在前一种情况下,程序可能会建议用户再次尝试保存文档,但在后一种情况下,文档可能会消失
(*)如果在发生Dispose时没有异常挂起,并且Dispose无法执行所需的清理,那么很明显应该抛出异常。另一方面,如果异常已经挂起,则从Dispose抛出将销毁先前异常保存的所有信息。我更喜欢的风格是使用Dispose(Exception Ex)方法,如果Dispose失败,该方法会将Ex作为内部异常传递,但如果没有语言支持,这种事情只能在vb.net中使用笨拙的语法,在C#中使用可疑的行为来支持。可能重复感谢,但它如何知道调用Close方法?“它实际上是由Dispose方法调用的吗?”琼·文奇(Joan Venge)反过来说——请参阅问题@ClosureCowboy linked to中的公认答案
using
调用IDisposable
的Dispose方法,Close也会调用该方法。请查看@djacobson:Close
调用Dispose
或反之亦然是否是一个实现细节。在StreamWriter
的情况下,调用Dispose
的确实是Close
,但在SqlDataReader
中,例如,Dispose
方法调用Close
。(当然,无论哪种方式,最终结果都是一样的。)
using ( var sw = new StreamWriter ( file ) )
{
XmlSerializer xs = new XmlSerializer ( typeof ( T ) );
xs.Serialize ( sw, data );
sw.Close()
}