Поймать Исключение лечения - PullRequest
3 голосов
/ 31 октября 2009

Какая разница между

catch(Exception ex)
{
   ...
   throw ex;
}

и использование

catch   //  might include  (Exception) 
{
   ...
   throw;
}

Ответы [ 5 ]

12 голосов
/ 31 октября 2009

throw ex повторно выбрасывает объект исключения из этой точки. Как правило, это плохо, так как уничтожает полезную информацию стека вызовов, которая приводит к исходной проблеме.

throw освобождает исходное пойманное исключение с того момента, как оно было фактически выдано. Он сохраняет информацию стека вызовов до этой точки, а не до точки, которую вы поймали.

catch(Exception) и catch - это, по сути, одно и то же, за исключением того, что первый дает вам объект исключения для каких-либо действий, а второй нет. Но оба поймают все исключения. Они отличаются от catch(SomeKindOfException), который будет перехватывать только исключения этого конкретного типа (или более конкретные типы, производные от этого типа). Это лучше всего подходит для таких ситуаций, как:

try
{
    //some file operation
}
catch(FileNotFoundException fnfex)
{
    //file not found - we know how to handle this
}
//any other kind of exception,
//which we did not expect and can't know how to handle,
//will not be caught and throw normally
4 голосов
/ 31 октября 2009

Использование catch без параметра было полезно в framework 1.x для отлова исключений, генерируемых из неуправляемого кода. Начиная с версии фреймворка 2 (IIRC) все неуправляемые исключения обернуты в управляемый объект Exception, поэтому для перехвата без параметров больше нет необходимости.

Бросок без параметров не является специфическим для улова без параметров, его можно использовать в любом блоке улова. Разница в том, что при повторном отбрасывании исключения с использованием throw; он не перезаписывает трассировку стека с момента первоначального создания исключения, так что это правильный способ перезапуска исключения.

Вместо использования throw ex; в блоке перехвата вы должны сгенерировать вновь созданное исключение, содержащее информацию, которую вы хотите добавить, с исходным исключением в качестве внутреннего исключения. Таким образом, вы получаете и исходную точку отказа, и точку, где вы поймали ее и перебросили.

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

catch (Exception ex) {
   ...
   throw;
}

или вы выбросили новое исключение с внутренним исключением:

catch (Exception ex) {
   ...
   throw new ApplicationException("Ooops!", ex);
}

Обратите внимание, что вы редко должны ловить базовый класс Exception, но более конкретный класс исключений, который подходит для ожидаемой ошибки. Обычно нет смысла перехватывать исключение, которое вы не знаете, как обработать.

1 голос
/ 31 октября 2009

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

Кроме того, «catch» будет ловить все, что выбрасывается, независимо от того, является ли оно исключением.

Второй фактически эквивалентен выполнению "catch (object)".

0 голосов
/ 31 октября 2009

Насколько я знаю, это одно и то же (с использованием Exception .., потому что все исключения происходят из этого класса). Это становится другим, когда вы ловите только ребенка Исключения ... или когда у вас есть несколько "уловов", ловящих разных детей. Возможно также, что вы перехватываете Exception, изменяете сообщение и выбрасываете его обратно.

0 голосов
/ 31 октября 2009

Первый сбрасывает свойство трассировки стека в выброшенном исключении

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