如果使用`using`语句,何时需要调用IDisposable?

我正在读另一个答案。 它让我想知道,如果我使用using语句,何时需要显式调用Dispose?

编辑:

只是为了certificate自己不知道什么,我问的原因是因为有人在另一个线程上说某些暗示有一个很好的理由不得不手动调用Dispose …所以我想,为什么不问一下呢?

你没有。 using语句为您完成。


根据MSDN ,这个代码示例:

 using (Font font1 = new Font("Arial", 10.0f)) { byte charset = font1.GdiCharSet; } 

在编译时,扩展为以下代码(注意额外的花括号以创建对象的有限范围):

 { Font font1 = new Font("Arial", 10.0f); try { byte charset = font1.GdiCharSet; } finally { if (font1 != null) ((IDisposable)font1).Dispose(); } } 

注意:正如@timvw所提到的 ,如果在using语句本身链接方法或使用对象初始值设定项并抛出exception,则不会处理该对象。 如果你看看它将扩展到什么是有道理的。 例如:

 using(var cat = new Cat().AsDog()) { // Pretend a cat is a dog } 

扩展到

 { var cat = new Cat().AsDog(); // Throws try { // Never reached } finally { if (cat != null) ((IDisposable)cat).Dispose(); } } 

AsDog显然会抛出exception,因为猫永远不会像狗一样出色。 然后猫永远不会被处理掉。 当然,有些人可能会争辩说猫永远不应该被处理掉,但那是另一个讨论……

无论如何,只要确保你using( here )所做的事情是安全的,你就可以去。 (显然,如果构造函数失败,则不会创建对象,因此不需要处置)。

通常你没有。 这是using语句的要点。 但是有一种情况你需要小心:

如果将变量重新分配给另一个值,则using语句将仅对原始值调用Dispose方法。

 using (someValue = new DisposableObject()) { someValue = someOtherValue; } 

编译器甚至会给你一个警告

可能是对本地’someValue’的赋值不正确,它是using语句或lock语句的参数。 Dispose调用或解锁将发生在本地的原始值上。

但是在使用c#3.0对象初始化器时要小心。 可以在此处找到一个示例: http : //ayende.com/Blog/archive/2009/01/15/avoid-object-initializers-amp-the-using-statement.aspx

决不。 一旦使用块内的语句完成执行,它将调用Dispose。

using语句的重点是如果你的对象实现了IDisposable,那么将在代码块的末尾调用dipose。 这就是它的用途,为你自动完成它。

我所知道的

 using (var myDisposable = new MyDisposable()) { ... } 

基本上是由编译器翻译成的

 var myDisposable = new MyDisposable() try { ... } finally { myDisposable.Dispose(); }