使用使用范围时,是否必须调用Close方法?

时间:2011-02-14 23:26:33

标签: c# .net dispose

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

我知道您不必致电Dispose,但是您是否必须在Close上拨打sw方法?

2 个答案:

答案 0 :(得分:8)

没有!你不必。它由“使用”

处理

答案 1 :(得分:2)

IDisposable背后的整个想法是,如果调用IDisposable.Dispose方法,实现的类将执行“合理”清理所需的任何操作。 Dispose执行的确切操作可能会根据对象的状态而有所不同,并且可能并不总是所需的清理方式。例如,如果在没有首先调用“提交”方法的情况下处理它,则命令/事务对象可以执行回滚。这会将命令/事务恢复到“安全”状态,但不一定是预期的状态。

另请注意,在涉及明确的“关闭”,确定性“处置”或非确定性“最终确定”(由于放弃对象而产生)的情况下,错误处理可能会有所不同。从语义上讲,一个不会导致闭合对象处于正确状态的“关闭”操作应该抛出异常。 Dispose方法应该这样做不太清楚。(*)有些类会从失败的dispose中抛出而其他类则不会抛出。如果一个对象被放弃并且在finalize期间出现问题,很少有类会提供任何通知,因为没有好的机制来处理它。如果保存文档结束时的“关闭”操作因某人过早拔出USB驱动器而失败,则应用程序可以通知用户文档可能没有保存,并且用户可以相应地采取行动。如果应用程序放弃了文件对象,那么“关闭”操作直到一段时间后才会发生,此时USB驱动器已被移除,应用程序无法处理错误。在前一种情况下,程序可能会建议用户再次尝试保存文档,但在后一种情况下,文档可能会消失。

(*)如果发生Dispose时没有异常挂起,并且Dispose无法执行其所需的清理,则很明显应该抛出异常。另一方面,如果异常已经挂起,则从Dispose中抛出将破坏先前异常所持有的所有信息。我首选的样式是使用Dispose(Exception Ex)方法,如果Dispose失败,它将Ex作为内部异常传递,但是如果没有语言支持,这样的东西只能在vb.net中使用笨拙的语法支持,并且具有可疑的行为在C#。