我正在调用第三方库,其中有很多类实现了IDisposable。
我是否需要在所有这些模式上使用模式?
答案 0 :(得分:5)
你没有拥有,但这是一种很好的做法。
无论是否发生异常,它都能确保正确清理资源。
IDisposable
只应在需要清理资源的类上实现,因此确保它们是好的做法。
可能会出现直接调用Dispose
而不是使用块的情况(WCF代理因此而臭名昭着),但这不是一般情况。
简而言之 - 没有人会强迫你使用它们,但你真的应该这样做。
答案 1 :(得分:3)
你不需要这样做,但你很可能应该这样做。
如果你不这样做,你可能会耗尽一些资源,或者甚至可能得到不正确的结果,具体取决于该库的确切做法。
但是,如果不知道Dispose()
对这些对象做了什么,你一定要调用它,以避免意外问题。 (并且您不必直接执行此操作,您可以使用using
按照您的建议执行此操作。)
答案 2 :(得分:3)
这在很大程度上取决于相关变量的范围。
如果变量是本地范围的,是的,您应该将相关代码括在using
块中。请记住,using
块只是以下语法糖,假设using
包含名为obj
的IDisposable对象:
var obj = // ...
try
{
// ...
}
finally
{
obj.Dispose();
}
这意味着即使抛出异常,您的对象也会被处理掉。
如果您的对象的范围是在类级别,那么不,您不应该将其封闭在using
块中。相反,您的类应该通过实现Dispose
将IDisposable
方法暴露给使用它的任何代码,并将对象置于那里。
通常,通过依靠类的终结器来处理其对象,将处理责任转移到此依赖关系链中的任何位置都是不好的做法。这会破坏Dispose
和Finalize
之间的差异:Dispose
用于显式的即时资源释放,而Finalize
则更为被动。依靠Finalize
来呼叫Dispose
,就会破坏目的的分离。然而,这更像是我编程风格的问题,并代表了一种观点 - 不要把它当成事实。在接受我的建议之前,你应该自己研究这个 - 并且肯定会阅读关于此事的不可避免的一系列评论。我确信我至少错过了重要的例外情况。
答案 3 :(得分:0)
当一个类实现IDisposable时,它表示它宁愿由你的代码处理,而不是等待垃圾收集器稍后处理它。所以是的,如果一个类实现了IDisposable,你应该在它超出范围之前调用Dispose(或使用using)。
您是否应该使用而不是直接调用Dispose?再次,是的。为了确保处置对象,您必须通过将代码封装在try {...} finally {}块中,即使抛出异常也要确保对象处置,这将阻止您将对象放在finally块中。这会导致不必要的混乱,您很容易忘记添加finally块。
使用这项工作要安全得多。