5

如果我使用using关键字,我还需要实现IDisposable吗?

4

7 回答 7

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。

于 2010-08-23T04:40:18.700 回答
12

如果您使用该using语句,则包含的类型必须已经实现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. 
}
于 2010-08-23T04:34:57.200 回答
5

你把事情弄糊涂了。您只能在实现 IDisposable 的东西上使用“using”关键字。

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

于 2010-08-23T04:32:05.183 回答
4

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

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

编辑:一个有用的例子。

当您发现自己在 finally 部分中始终如一地做事时,例如在将光标设置为等待光标后将其重置为默认值,这是此模式的候选者...

  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.
}
于 2010-08-23T04:40:42.023 回答
2

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

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

通常,当您使用 IDisposable 对象时,您应该在 using 语句中声明和实例化它。using 语句以正确的方式调用对象上的 Dispose 方法,并且一旦调用 Dispose,它还会导致对象本身超出范围。在 using 块中,对象是只读的,不能修改或重新分配。

using 语句可确保调用 Dispose,即使在调用对象上的方法时发生异常也是如此。您可以通过将对象放在 try 块中,然后在 finally 块中调用 Dispose 来获得相同的结果;事实上,这就是编译器翻译 using 语句的方式。

于 2010-08-23T04:32:17.580 回答
1

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

于 2010-08-23T11:46:37.503 回答
1

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

error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'
于 2010-08-23T12:45:09.107 回答