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

あなたは物事を混乱させています。「using」キーワードは、IDisposableを実装するものにのみ使用できます。

編集:usingキーワードを使用する場合、明示的にDisposeを呼び出す必要はありません。これは、usingブロックの最後で自動的に呼び出されます。他の人は、usingステートメントがどのようにtry-finallyステートメントに変換され、finallyブロック内でDisposeが呼び出されるかの例をすでに投稿しています。

于 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を実装する必要があります。IDisposableを実装していない型でusing()を使用しようとすると、次のコンパイル時エラーが発生します。

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