7

Constructor メソッドと Process メソッドが例外をスローする可能性があると仮定すると、Disposable オブジェクトを使用するための最良の方法は何ですか? 私は通常、以下の実装のいずれかを好みます。

  1. ブロックを使って周囲をトライキャッチ

    try
    {
        using (Disposable dispObj = new Disposable())
        {
            dispObj.Process();
        }
    }
    catch (Exception ex)
    {
        // Do something
    }
    
  2. try-catch-finally ブロック。

    Disposable dispObj2 = null;
    try
    {
        dispObj2 = new Disposable();
        dispObj2.Process();
    }
    catch (Exception ex)
    {
        // Do something
    }
    finally
    {
        if (dispObj2 != null)
        {
            dispObj2.Dispose();
        }
    }
    

アップデート:

繰り返しますが、「コンストラクターとプロセスのメソッドが例外をスローする可能性があると想定しています」。なぜ誰も答えの例外を気にしなかったのか、私には本当にわかりません。

4

8 に答える 8

10

usingいいね。組み込みの try-finally ブロックがあります。例外が発生した場合、dispose メソッドが自動的に呼び出されます。

これでいい

using (Disposable dispObj = new Disposable())
{
    dispObj.Process();
}
于 2012-08-01T09:19:20.673 に答える
3

次のようにします。

using (Disposable dispObj = new Disposable())
{
    dispObj.Process();
}

using破棄可能なオブジェクトは、例外によるものであっても、節の範囲外になると常に破棄されます。

catch {}そして、完全に無意味な空の を使用しないでください。

于 2012-08-01T09:20:30.613 に答える
3

using ステートメントは try - finally をバックグラウンドで使用し、IDisposable を実装するオブジェクトでのみ機能します。using で try catch を使用する必要はありません。次の例を見てください ( MSDN から - using statement )。

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();
  }
于 2012-08-01T09:23:52.463 に答える
2
using (Disposable dispObj = new Disposable())
    {
        dispObj.Process();
    }
}
于 2012-08-01T09:20:18.730 に答える
1

通常、IDisposable インターフェイスを実装するクラスは、.NET フレームワークのガベージ コレクターではクリーンアップできないリソースを使用します。IDisposable.Dispose() メソッドを呼び出すと、貴重なリソースを明示的に世界に解放するコードが実行されます。IDisposable インターフェイスを実装するクラスの代表的な例は、SqlConnection クラスです。SqlConnection クラスは、Microsoft SQL Server データベース接続を使用します。SQL Server は限られた数の接続をサポートするため、できるだけ早く接続を解放することが重要です。通常、Dispose() メソッドを直接呼び出すことはありません。通常、コードで言及したように、コードで Using ステートメントを利用します

于 2012-08-01T09:21:48.833 に答える
0
using (IDisposable disp = new IDisposable())
{
   //some logic here
}

このコードは次のように翻訳されます。

IDisposable disp = new IDisposable();

try
{
  //some logic here
}
finally
{
  if (disp != null)
     ((IDisposable)disp).Dispose();
}

ブロック内のコードは「finally」で常に実行されるため、例外をスローする可能性があり、Disposeが呼び出されないことを疑うことなくブロックの使用から戻ることができます。

ただし、オブジェクト初期化子の使用には注意する必要があります。

using (var fs = new FileStream(@"C:\blabla", FileMode.Open) { Position = pos })
{
    //some logic here
}

ここからわかるように、プロパティPositionは例外をスローできます。そして問題は、オブジェクトが作成され、これがtryブロックから実行されるため、メモリリークが発生する可能性があることです。これへの正しい道

using (var fs = new FileStream(@"C:\blabla", FileMode.Open))
{
    fs.Position = pos;
    //some logic here
}
于 2012-08-01T09:41:06.853 に答える
0

可能であれば、using ブロックを使用する必要があります。オブジェクトで Dispose が呼び出されることが保証されます。手動で行うとエラーが発生しやすくなります。

于 2012-08-01T09:20:40.380 に答える