我是否需要在实现IDisposable的每个对象中使用“using”关键字?

时间:2012-02-09 14:11:58

标签: c# .net idisposable using-statement

我正在调用第三方库,其中有很多类实现了IDisposable。

我是否需要在所有这些模式上使用模式?

4 个答案:

答案 0 :(得分:5)

你没有拥有,但这是一种很好的做法。

无论是否发生异常,它都能确保正确清理资源。

IDisposable只应在需要清理资源的类上实现,因此确保它们是好的做法。

可能会出现直接调用Dispose而不是使用块的情况(WCF代理因此而臭名昭着),但这不是一般情况。

简而言之 - 没有人会强迫你使用它们,但你真的应该这样做。

答案 1 :(得分:3)

你不需要这样做,但你很可能应该这样做。

如果你不这样做,你可能会耗尽一些资源,或者甚至可能得到不正确的结果,具体取决于该库的确切做法。

但是,如果不知道Dispose()对这些对象做了什么,你一定要调用它,以避免意外问题。 (并且您不必直接执行此操作,您可以使用using按照您的建议执行此操作。)

答案 2 :(得分:3)

这在很大程度上取决于相关变量的范围。

本地范围:使用

如果变量是本地范围的,是的,您应该将相关代码括在using块中。请记住,using块只是以下语法糖,假设using包含名为obj的IDisposable对象:

var obj = // ...
try
{
    // ...
}
finally
{
    obj.Dispose();
}

这意味着即使抛出异常,您的对象也会被处理掉。

班级范围:IDisposable

如果您的对象的范围是在类级别,那么不,您不应该将其封闭在using块中。相反,您的类应该通过实现DisposeIDisposable方法暴露给使用它的任何代码,并将对象置于那里。

从不使用:完成

通常,通过依靠类的终结器来处理其对象,将处理责任转移到此依赖关系链中的任何位置都是不好的做法。这会破坏DisposeFinalize之间的差异:Dispose用于显式的即时资源释放,而Finalize则更为被动。依靠Finalize来呼叫Dispose,就会破坏目的的分离。然而,这更像是我编程风格的问题,并代表了一种观点 - 不要把它当成事实。在接受我的建议之前,你应该自己研究这个 - 并且肯定会阅读关于此事的不可避免的一系列评论。我确信我至少错过了重要的例外情况。

答案 3 :(得分:0)

当一个类实现IDisposable时,它表示它宁愿由你的代码处理,而不是等待垃圾收集器稍后处理它。所以是的,如果一个类实现了IDisposable,你应该在它超出范围之前调用Dispose(或使用using)。

您是否应该使用而不是直接调用Dispose?再次,是的。为了确保处置对象,您必须通过将代码封装在try {...} finally {}块中,即使抛出异常也要确保对象处置,这将阻止您将对象放在finally块中。这会导致不必要的混乱,您很容易忘记添加finally块。

使用这项工作要安全得多。