我正在调用一个第三方库,其中有很多类都实现了IDisposable接口。
我是否需要在所有这些类上使用using模式?
我正在调用一个第三方库,其中有很多类都实现了IDisposable接口。
我是否需要在所有这些类上使用using模式?
你不必须这么做,但这是一个好的实践。
它确保资源被正确清理,无论是否发生异常。
IDisposable
只应该在需要清理资源的类上实现,因此确保它们这样做是一个好的实践。
可能会有一些情况需要直接调用Dispose
而不是使用块(WCF代理就是臭名昭著的例子),但这并不是常规情况。
简而言之 - 没有人会强制你使用它们,但你真的真的应该这样做。
这要根据变量的作用域来决定。
如果该变量具有本地作用域,是的,应该在相关代码中使用 using
块。请记住,using
块只是语法糖,假设 using
封装了一个名为 obj
的 IDisposable 对象,则相当于以下代码:
var obj = // ...
try
{
// ...
}
finally
{
obj.Dispose();
}
这意味着,即使出现异常,您的对象也将被处理。
如果��的对象作用域在类级别,则不应将其包含在using
块中。相反,您的类应通过实现IDisposable
来向使用它的任何代码公开Dispose
方法,并在那里处理该对象。
通常情况下,依靠类的finalizer来释放其对象的处理责任,会破坏此依赖关系链中的任何点,并不是好的做法。这会削弱Dispose
和Finalize
之间的区别: Dispose
用于显式、立即释放资源,而Finalize
则更为被动。但是,这更多是我个人的编程风格和观点,不要把它当作事实。您应该自行进行更多的研究,特别是阅读相关评论,然后再采纳我的建议。我肯定错过了重要的例外,至少是其中之一。
Finalize
。 - ZenexerDispose
更好。对于类级别的变量,使用 using
没有意义。 - ZenexerFinalize
命名”。如果一个类覆盖了 Object.Finalize()
,那么对象在该方法被调用或使用 GC.SuppressFinalize()
指示它不必要之前,将不会被垃圾回收。由于几乎每个使用 C# 析构函数的程序都需要正确(析构函数是一种语法单元,请求编译器覆盖 Object.Finalize
)包括调用GC.SuppressFinalize()
方法,因此“finalize”这个术语似乎比“destructor”更合适,尽管后者术语仍然需要描述C#包装器。 - supercatFinalize
有很多合适的理由(这也是我使用它的原因),但你会惊讶地发现有多少人听到它就会尖叫“Java!”。不过,你的解释非常好。 - Zenexer你“不一定需要”这样做,但最好这样做。
如果你不这样做,你可能会耗尽一些资源,或者根据该库的具体作用,甚至会得到错误的结果。
但是如果不知道Dispose()
对这些对象具体执行了什么操作,为避免出现意外问题,确实应该调用它。(而且你不必直接调用,可以使用using
来处理,就像你建议的那样。)
你应该使用using而不是直接调用Dispose吗?同样是的。为确保对象被处理,即使抛出异常,您也必须确保您的对象已经被处理,通过将您的代码封装在try {...} finally {}块中,在finally块中处理您的对象。这会导致不必要的混乱,并且您可能会轻易地忘记添加finally块。
使用using更加安全可靠。
new
或工厂方法创建的对象)调用Dispose。使用using
块是实现这一点的简单方法。 - Rich O'Kelly