8

Catch(Exception)とはどう違いますかCatch(Exception ex)?どちらも期待どおりの出力を示していることがわかります。それでは、実際の違いは何ですか?どれがおすすめ?

コードが以下であるとします。

int a = 1, b = 0;
try
{
    int c = a / b;
    Console.WriteLine(c);
}

以下の catch ブロックのどれを使用することをお勧めしますか? それらの実際の違いは何ですか?

catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

また

catch (Exception)
{
    Console.WriteLine("Oh NO!!");
}
4

6 に答える 6

5

1 つだけ違いがあります:catch(Exception ex)例外クラス(エラー原因) インスタンスへのアクセスがあります。通常、元のメッセージを出力するには、例外クラスのインスタンスが必要です。catch(Exception)catch(Exception ex)

  try {
    ...
  }
  catch (AppServerException e) {
    Console.WriteLine("Application server failed to get data with the message:");
    Console.WriteLine(e.Message); // <- What's actually got wrong with it
  }

例外クラスのインスタンスが必要ない場合、たとえば、例外を消費するだけの場合は、catch(Exception ex) 構文が過剰であり、catch(Exception) が優先されます。

  try {  
    c = a / b;
  }  
  catch (DivideByZeroException) {
    c = Int.MaxValue; // <- in case b = 0, let c be the maximum possible int
  }

ついに。再スルーせずに一般的な例外クラスをキャッチしないでください:

  try {
    int c = a / b;
  }
  catch (Exception) { // <- Never ever do this!
    Console.WriteLine("Oh NO!!");
  }

「エラー (CPU からの緑色の煙を含む) が発生した場合は、単に "Oh No" を出力して続行する」をコーディングしますか? Exception クラスのパターンは次のようなものです。

  tran.Start();

  try {
    ...
    tran.Commit();
  }
  catch (Exception) {
    // Whatever had happened, let's first rollback the database transaction
    tran.Rollback();

    Console.WriteLine("Oh NO!");

    throw; // <- re-throw the exception
  }
于 2013-08-11T16:16:14.750 に答える
3

それは非常に簡単です:

  • 最初のコードでは、例外をキャッチしてそれを表すオブジェクトを取得できるため、何が起こったのかについてより多くの情報を得ることができます
  • 2 番目のコードでは、例外が発生したことしかわかりませんが、それに関する詳細情報はありません。

実際に何を使用するかは、発生した例外についてどれだけの情報を取得したいかによって異なります。

于 2013-08-11T15:00:33.253 に答える
2

catchブロック内で例外を使用する必要がある場合はException、名前を付けます。それ以外の場合は、匿名にしてください。

catchブロックが単に例外のメッセージを表示する以上のことをする必要がある場合があります。たとえば、アプリケーション固有の例外をキャッチすると、例外オブジェクトの追加要素を調べることができる場合があります。以下は架空の例です。

catch (ConnectToServerException cse) {
    MessageBox.Show(string.Format(
        "Connection to server '{0}' failed. Use a name from the following list: {1}"
    ,   cse.AttemptedConnectionServerName
    ,   string.Join(", ", cse.AllowedServerNames)
    ));
}

上記のコードは、カスタム例外に、接続しようとしたサーバーの名前でConnectToServerException呼び出されるプロパティと、使用可能なサーバーの名前を含む列挙プロパティがあることを前提としています。AttemptedConnectionServerNameAllowedServerNames

特定のタイプの例外が発生したことだけを知る必要がある場合もあります。この場合、名前付き変数を指定する必要はありません。

于 2013-08-11T15:00:49.223 に答える
0

Catch (Exception)それも型なので、同じことをしてくださいException

Catch (Exception ex)すべての例外をキャッチし、さらにその参照を通じてメッセージを取得できます。

使用は要件に依存します。例外メッセージを表示したい場合は、ex.Messageそれ以外の場合Catch (Exception)は使用する機能で十分です。

于 2013-08-11T15:01:42.433 に答える
0

違いは、ゼロで除算しようとしたと出力されることです。もう一方はOh NO!!と表示されます。.

例外の処理は複雑な問題であり、アプリケーションによって異なりますが、一般的なコメントはいくつかあります。


一般的に言えば、特定の例外のハンドラーを提供するのが最善です。

何かのようなもの:

 catch ({System.DivideByZeroException ex )
 {
    Console.WriteLine("Ops. I cannot divide by zero." );
 }
 catch ({System.Exception ex )
 {
    Console.WriteLine("There was an error during calculations: {0}", ex.Message );
 }

遅かれ早かれ、それConsole.WriteLineだけでは不十分であることがわかり、ロガーを使用する必要があるため、早期に使用を開始するのが最善です.


理想的には、生のエラー メッセージをユーザーに公開する場合は、例外チェーン内のすべてのメッセージ、または少なくとも最も深いメッセージを出力する必要があります。

何かのようなもの:

 catch ({System.DivideByZeroException ex )
 {
    Console.WriteLine("Oops. I cannot divide by zero." );
 }
 catch ({System.Exception ex )
 {
    Console.WriteLine(GetExceptionMsgs(ex));
 }

 ...in another class...
public static string GetExceptionMsgs(Exception ex) {
   if( ex == null ) {
       return "No exception = no details";
   }
   var sb = new StringBuilder();
   while( ex != null ) {
        sb.AppendLine(ex.Message);
        ex = ex.InnerException;
   }
   return sb.ToString()
}
于 2013-08-11T15:24:39.470 に答える
0

そのcatchブロックで処理する例外の種類を指定するだけです(このcatch(Exception)場合、発生するすべての例外なので、単にと同じになりますcatch

発生した実際の例外のインスタンスを渡すとcatch(Exception ex)、例外のプロパティにアクセスして、提供された情報で何かを行うことができます。

于 2013-08-11T15:05:38.793 に答える