web-dev-qa-db-ja.com

同じcatchブロックで2つの例外をキャッチしますか?

CommuncationExceptionSystemExceptionの2つの異なる例外をスローできるメソッドがあります。どちらの場合も、同じ3行のコードブロックを実行します。

try {
 ...
}

catch (CommunicationException ce) {
   ...
}

catch {SystemExcetion se) {
   ... 
}

そのようなことをする可能性はありますか?

try {
   ...
}

catch (CommunicationException ce, SystemException se) {
   ...
}

そうすれば、これほど多くのコードを書く必要はありません。例外処理をプライベートメソッドに抽出できることは知っていますが、コードは3行しかないため、メソッド定義には本体自体よりも多くのコードが必要です。

38

実際、SystemExceptionのみをキャッチでき、CommunicationExceptionCommunicationExceptionから派生しているため、SystemExceptionも処理できます。

catch (SystemException se) {
   ... //this handles both exceptions
}
25
archil

アプリケーションをC#6にアップグレードできる場合、幸運です。 新しいC#バージョンには例外フィルターが実装されています 。だからあなたはこれを書くことができます:

catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
    //handle it
}

このコードは次のものと同じだと思う人もいます

catch (Exception ex) {                
    if (ex is CommunicationException || ex is SystemException) {
        //handle it
    }
    throw;
}

しかし、そうではありません。実際、これは以前のバージョンでエミュレートできないC#6の唯一の新機能です。まず、再スローはキャッチをスキップするよりもオーバーヘッドが大きいことを意味します。第二に、それは意味的に同等ではありません。新しい機能は、コードをデバッグするときにスタックをそのまま保持します。この機能がないと、クラッシュダンプはあまり役に立たないか、役に立たなくなります。

CodePlexでこれについての議論 を参照してください。 違いを示す例

147
Maniero

残念ながら、方法はありません。使用した構文は無効であり、switchステートメントのようなフォールスルーも不可能です。私はあなたがプライベートな方法で行く必要があると思います。

少しハッキーな回避策は次のようになります。

var exceptionHandler = new Action<Exception>(e => { /* your three lines */ });
try
{
    // code that throws
}
catch(CommuncationException ex)
{
    exceptionHandler(ex);
}
catch(SystemException ex)
{
    exceptionHandler(ex);
}

これが意味をなすかどうかは、自分で決める必要があります。

11
Daniel Hilgarth

いいえ、そのようにすることはできません。私が知っている唯一の方法は、一般的な例外をキャッチして、それがどのようなタイプであるかを確認することです:

try
{
   ...
}
catch(Exception ex)
{
   if(ex is CommunicationException || ex is SystemException)
   {
      ...
   }
   else
   {
     ... // throw; if you don't want to handle it
   }
}
5
alexn

どう?

try {


...
}

catch (CommunicationException ce) {
   HandleMyError(ce);
}

catch {SystemExcetion se) {
   HandleMyError(se);
}

private void HandleMyError(Exception ex)
{
// handle your error
}
3
Gerrie Schenck

可能な重複

一度に複数の例外をキャッチしますか?

私はここに答えを引用します:

 catch (Exception ex)            
       {                
           if (ex is FormatException ||
               ex is OverflowException)
           {
               WebId = Guid.Empty;
               return;
           }
           else
           {
               throw;
           }
       }
3
Marshal

あなたは両方のタイプの例外に対して同じことをしているので、あなたはただ行くことができます:

try
{
    //do stuff
}
catch(Exception ex)
{
    //normal exception handling here
}

独自の何かを行う必要がある場合にのみ、明示的な例外タイプをキャッチしてください。

1
tobias86