web-dev-qa-db-ja.com

try / catch + using、正しい構文

どれ:

using (var myObject = new MyClass())
{
   try
   {
      // something here...
   }
   catch(Exception ex)
   {
      // Handle exception
   }
}

OR

try
{
   using (var myObject = new MyClass())
   {
      // something here...
   }
}
catch(Exception ex)
{
   // Handle exception
}
175
Xaqron

私は2番目のものを好む。同様に、オブジェクトの作成に関連するエラーもトラップする場合があります。

88
Jonathan Wood

Usingブロックはtry/finally( MSDN )の単なる構文簡略化であるため、個人的には次の方法を使用しますが、2番目のオプションとは大きく異なることを疑います。

MyClass myObject = null;
try {
  myObject = new MyClass();
  //important stuff
} catch (Exception ex) {
  //handle exception
} finally {
  if(myObject is IDisposable) myObject.Dispose();
}
34
chezy525

場合によります。 Windows Communication Foundation(WCF)を使用している場合、usingステートメントのプロキシが例外状態の場合、using(...) { try... }は正しく動作しません。つまり、このプロキシを破棄すると別の例外が発生します。

個人的には、最小限の処理アプローチ、つまり、実行時に認識している例外のみを処理することを信じています。言い換えると、usingの変数の初期化が特定の例外をスローする可能性があることがわかっている場合は、try-catchでラップします。同様に、usingボディ内でusingの変数に直接関連しない何かが発生する可能性がある場合は、その特定の例外に対して別のtryでラップします。 Exceptionesでcatchを使用することはほとんどありません。

しかし、私はIDisposableusingが好きなので、偏っているかもしれません。

19
Schultz9999

Catchステートメントがusingステートメントで宣言された変数にアクセスする必要がある場合、内部が唯一のオプションです。

Catchステートメントで、usingで参照されるオブジェクトを破棄する前に必要とする場合、内部が唯一のオプションです。

ユーザーにメッセージを表示するなど、不明な期間のアクションをcatchステートメントが実行し、それが発生する前にリソースを破棄したい場合は、外部が最適なオプションです。

これに似たscenerioがあるときはいつでも、try-catchブロックは通常、使用からコールスタックのさらに上の別のメソッドにあります。このようにメソッド内で発生する例外を処理する方法をメソッドが知ることは一般的ではありません。

したがって、私の一般的な推奨事項は外にあります。

private void saveButton_Click(object sender, EventArgs args)
{
    try
    {
        SaveFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}
19

両方とも有効な構文です。それは本当にあなたがしたいことです:オブジェクトの作成/破棄に関連するエラーをキャッチしたい場合は、2番目を使用します。そうでない場合は、最初のものを使用します。

9
Smashery

ここで重要なことが1つあります。最初のものはnotMyClassコンストラクターの呼び出しに起因する例外をキャッチします。

6
Madhur Ahuja

Using()ブロックで初期化するオブジェクトが例外をスローする可能性がある場合は、2番目の構文を使用する必要があります。

私のシナリオでは、ファイルを開かなければならず、Using()ブロックで初期化していたオブジェクトのコンストラクターでfilePathを渡していましたが、filePathが間違っている/空の場合は例外をスローする可能性があります。したがって、この場合、2番目の構文が意味をなします。

私のサンプルコード:-

try
{
    using (var obj= new MyClass("fileName.extension"))
    {

    }
}
catch(Exception ex)
{
     //Take actions according to the exception.
}
1
Ankur Arora