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

时间:2009-02-13 07:33:40

标签: c# .net

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

编辑:

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

6 个答案:

答案 0 :(得分:20)

你没有。 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 mentioned,如果在using语句本身链接方法或使用对象初始值设定项并抛出异常,则不会处理该对象。如果你看看它将扩展到什么是有道理的。例如:

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显然会抛出异常,因为猫永远不会像狗一样出色。然后猫永远不会被处理掉。当然,有些人可能会争辩说猫永远不应该被处理掉,但这是另一个讨论......

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

答案 1 :(得分:12)

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

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

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

编译器甚至会为您提供警告

  

可能错误地赋值给本地'someValue',这是using语句或lock语句的参数。处理呼叫或解锁将发生在本地的原始值上。

答案 2 :(得分:10)

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

答案 3 :(得分:5)

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

答案 4 :(得分:3)

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

答案 5 :(得分:3)

据我所知

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

基本上由编译器翻译为

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