Подтвердить что ты не робот

Ловить два исключения в одном блоке catch?

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

try {
 ...
}

catch (CommunicationException ce) {
   ...
}

catch {SystemExcetion se) {
   ... 
}

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

try {
   ...
}

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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;
}

Но это не так. На самом деле это единственная новая функция в С# 6, которую невозможно эмулировать в предыдущих версиях. Во-первых, повторный бросок означает больше накладных расходов, чем пропуск улова. Во-вторых, это не семантически эквивалентно. Новая функция сохраняет неиспользуемый стек при отладке вашего кода. Без этой функции аварийный сброс менее полезен или даже бесполезен.

См. обсуждение этого вопроса в CodePlex. И пример показывающий разницу.

Ответ 3

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

Немного взломанный рабочий процесс будет примерно таким:

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

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

Ответ 4

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

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

Ответ 5

Что насчет

try {


...
}

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

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

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

Ответ 7

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

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

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