using关键字和IDisposable接口之间有什么关系?

时间:2010-08-23 04:30:11

标签: c# .net idisposable using-statement resource-management

如果我使用的是using关键字,我是否还需要实施IDisposable

7 个答案:

答案 0 :(得分:13)

你不能没有另一个。

当你写:

using(MyClass myObj = new MyClass())
{
    myObj.SomeMthod(...);
}

编译器将生成如下内容:

MyClass myObj = null;
try
{
    myObj = new MyClass();
    myObj.SomeMthod(...);
}
finally
{
    if(myObj != null)
    {
        ((IDisposable)myObj).Dispose();
    }
} 

因此,当您使用using关键字时可以看到,假定/要求实现IDisposable。

答案 1 :(得分:12)

如果使用using statement,则封闭类型必须已实现IDisposable,否则编译器将发出错误。因此,将IDisposable实现视为使用的先决条件。

如果要在自定义类上使用using语句,则必须为其实现IDisposable。然而,这是一种落后的做法,因为没有任何意义这样做。只有当你有一些像处理非托管资源一样的东西时才应该实现它。

// To implement it in C#:
class MyClass : IDisposable {

    // other members in you class 

    public void Dispose() {
        // in its simplest form, but see MSDN documentation linked above
    }
}

这使您能够:

using (MyClass mc = new MyClass()) {

    // do some stuff with the instance...
    mc.DoThis();  //all fake method calls for example
    mc.DoThat();

}  // Here the .Dispose method will be automatically called.

实际上和写作一样:

MyClass mc = new MyClass();
try { 
    // do some stuff with the instance...
    mc.DoThis();  //all fake method calls for example
    mc.DoThat();
}
finally { // always runs
    mc.Dispose();  // Manual call. 
}

答案 2 :(得分:5)

你很困惑。您只能在实现IDisposable的内容上使用“using”关键字。

编辑:如果使用using关键字,则不必明确调用Dispose,它将在using块的末尾自动调用。其他人已经发布了如何将using语句转换为try-finally语句的示例,并在finally块中调用Dispose。

答案 3 :(得分:4)

是的,using关键字是这种模式的语法糖......(来自msdn)

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

编辑:一个有用的例子。

当你发现你正在最后一节中做一些事情时,例如在将Cursor设置为等待光标后将Cursor重置为默认值,这就是这种模式的候选者......

  public class Busy : IDisposable
  {

    private Cursor _oldCursor;

    private Busy()
    {
      _oldCursor = Cursor.Current;
    }

    public static Busy WaitCursor
    {
      get
      {
        Cursor.Current = Cursors.WaitCursor;
        return new Busy();
      }
    }

    #region IDisposable Members

    public void Dispose()
    {
      Cursor.Current = _oldCursor;
    }

    #endregion
  }

被称为......

using(Busy.WaitCursor)
{
  // some operation that needs a wait cursor.
}

答案 4 :(得分:2)

使用只会处理一次性对象。因此,在没有实现IDisposable 的对象周围包装一个使用块是相当无用的实际上会导致编译器错误。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

  

通常,当您使用IDisposable时   对象,你应该声明和   在using语句中实例化它。   using语句调用Dispose   方法对正确的对象   方式,它也导致对象   本身就要尽快超出范围   处理被称为。在使用中   块,该对象是只读的   无法修改或重新分配。

     

using语句确保了这一点   即使异常,也会调用Dispose   在调用方法时发生   在对象上。你可以实现   通过放置对象得到相同的结果   在try块内,然后调用   在最后一个块中处理;事实上,   这就是using语句的用法   由编译器翻译。

答案 5 :(得分:1)

using关键字已经实现,因此如果使用using关键字,则不必调用IDisposable

答案 6 :(得分:1)

您必须实现IDisposable才能使用。如果您尝试在未实现IDisposable的类型上使用using(),则会出现以下编译时错误:

error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'