Могу ли я выполнить несколько блоков Catch? - PullRequest
22 голосов
/ 27 октября 2010

Это немного абстрактно, но есть ли какой-нибудь возможный способ вызвать исключение и ввести его в несколько блоков catch?Например, если оно соответствует конкретному исключению, за которым следует неспецифическое исключение.

catch(Arithmetic exception)
{
  //do stuff
}
catch(Exception exception)
{
  //do stuff
}

Ответы [ 6 ]

37 голосов
/ 27 октября 2010

Вполне допустимо иметь несколько блоков захвата разных типов. Однако поведение таково, что первый блок-кандидат обрабатывает исключение.

Он не войдет в ОБА блоки. Первый блок catch, который соответствует типу исключения, будет обрабатывать это конкретное исключение, и никаких других, даже если оно было переброшено в обработчике. Любые последующие будут пропущены, как только исключение войдет в блок catch.

Для того, чтобы исключение было перехвачено в ОБАХ блоках, вам нужно либо вложить блоки так:

try
{
     try
     {
        // Do something that throws  ArithmeticException
     }
     catch(ArithmeticException arithException)
     {
        // This handles the thrown exception....

        throw;  // Rethrow so the outer handler sees it too
     }
}
catch (Exception e)
{
   // This gets hit as well, now, since the "inner" block rethrew the exception
}

В качестве альтернативы, вы можете фильтровать в универсальном обработчике исключений на основе определенного типа исключения.

21 голосов
/ 27 октября 2010

Нет. Невозможно выполнить код в обоих блоках catch для одного исключения.

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

try
{
   // blah blah blah
{
catch(Arithmetic ae)
{
   HandleArithmeticException( ae );
   HandleGenericException( ae );
}
catch(Exception e)
{
  HandleGenericException( e );
}
3 голосов
/ 27 октября 2010

Как и другие говорили, исключение будет перехвачено самым конкретным блоком перехвата.

Это вызывает у меня разочарование, хотя и с обработкой исключений. Я хотел бы, чтобы вы могли сделать что-то вроде

catch (ArgumentNullExcpetion, ArugmentOutOfRangeException ex)
{

}

Вместо того, чтобы делать

catch (ArgumentNullExcpetion e)
{
}
catch (ArugmentOutOfRangeException outOfRange)
{
}

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

2 голосов
/ 27 октября 2010

Если вы использовали VB.NET, вы могли бы абстрагировать свой обработчик ошибок в исключении Арифметика в вызов функции или метода, который всегда возвращает false.

Тогда вы могли бы написать что-то вроде:

Catch ex as Arithmetic When HandleArithmetic()
Catch ex as Exception

End Try

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

2 голосов
/ 27 октября 2010

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

catch (Exception exception)
{
    var aex = exception as ArithmeticException
    if (aex != null)
    {
        // do stuff specific to this exception type
    }
  // then do general stuff
}
0 голосов
/ 27 октября 2010

Это называется фильтрацией исключений и не поддерживается в C # (мне сказали, что это возможно в VB.NET).

Один из способов обойти это - поймать общее исключение и затем проверитьвведите исключение в блоке catch и выполните какую-либо конкретную обработку перед тем, как продолжить работу с остальной частью блока.

...