Поймать два исключения в одном блоке catch? - PullRequest
37 голосов
/ 06 апреля 2011

У меня есть метод, который может выдавать два разных исключения, CommuncationException и SystemException.В обоих случаях я делаю один и тот же трехстрочный кодовый блок.

try {
 ...
}

catch (CommunicationException ce) {
   ...
}

catch {SystemExcetion se) {
   ... 
}

Есть ли возможность сделать это так?

try {
   ...
}

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

Тогда мне не пришлось бы писать так многокод.Я знаю, что могу извлечь обработку исключений для закрытого метода, но, поскольку длина кода составляет всего 3 строки, определение метода займет больше кода, чем само тело.

Ответы [ 7 ]

143 голосов
/ 21 июля 2015

Если вы можете обновить свое приложение до 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 пример, показывающий разницу .

25 голосов
/ 06 апреля 2011

На самом деле, вы можете поймать только SystemException, и он будет обрабатывать CommunicationException, потому что CommunicationException является производным от SystemException

catch (SystemException se) {
   ... //this handles both exceptions
}
11 голосов
/ 06 апреля 2011

К сожалению, нет пути. Синтаксис, который вы использовали, недопустим, и провал, как в операторе switch, также невозможен. Я думаю, что вам нужно использовать приватный метод.

Небольшой хакерский обходной путь будет выглядеть примерно так:

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

Вы должны решить для себя, имеет ли это смысл.

5 голосов
/ 06 апреля 2011

Нет, вы не можете сделать это таким образом.Единственный известный мне способ - поймать универсальное исключение, а затем проверить, к какому типу оно относится:

try
{
   ...
}
catch(Exception ex)
{
   if(ex is CommunicationException || ex is SystemException)
   {
      ...
   }
   else
   {
     ... // throw; if you don't want to handle it
   }
}
3 голосов
/ 06 апреля 2011

Возможный Дубликат

Поймать несколько исключений одновременно?

Цитирую ответ здесь:

 catch (Exception ex)            
       {                
           if (ex is FormatException ||
               ex is OverflowException)
           {
               WebId = Guid.Empty;
               return;
           }
           else
           {
               throw;
           }
       }
3 голосов
/ 06 апреля 2011

А как же

try {


...
}

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

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

private void HandleMyError(Exception ex)
{
// handle your error
}
1 голос
/ 06 апреля 2011

Поскольку вы делаете то же самое для обоих типов исключений, вы можете просто пойти:

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

Улавливайте явные типы исключений только в том случае, если вам нужно сделать что-то уникальное для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...