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

В чем разница между тремя вариантами блоков catch в С# ('Catch', 'Catch (Exception)' и 'Catch (Exception e)')?

В С# в чем разница между 'Catch', 'Catch (Exception)' и 'Catch (Exception e)'?

статья MSDN в try-catch использует 2 из них в своих примерах, но не объясняет разницу в использовании.

try
{}
catch 
{}

try 
{}
catch (Exception)
{}

try
{}
catch(Exception e)
{}

Как они отличаются? Какие из них поймают все исключения и какие из них поймают определенные исключения?

4b9b3361

Ответ 1

Короче...

Catch без параметра получает какое-либо исключение, но не предоставляет никаких средств для его адресации.

Catch (Exception) будет по существу делать то же самое, потому что вы указали тип root Exception. В отличие от Catch (IOException), который будет только улавливать тип IOException.

Catch (Exception ex) захватывает все исключения и предоставляет средства для обращения к нему с помощью переменной ex.

Подробнее: http://msdn.microsoft.com/en-us/library/ms173160.aspx

Ответ 2

Никто еще не упомянул об историческом аспекте этого вопроса.

В .NET законно бросать объект, который не получается из Exception. (Это не является законным в С#, но он находится на некоторых других управляемых языках.) Многие люди не знают об этом факте, но это законно. Поскольку это безумие, в .NET 2.0 по умолчанию было изменено: если вы пытаетесь выбросить то, что не является исключением, оно автоматически завершается в класс RuntimeWrappedException, который, очевидно, является исключением. Затем этот объект бросается.

Из-за этой странности в С# 1.0 было обычным видеть код, который сделал оба:

try
{ do something }
catch(Exception) 
{ handle the exception }
catch
{ handle the thrown non-exception }

И на самом деле были проблемы с безопасностью и корректностью; есть ситуации, в которых по соображениям безопасности вы должны поймать все, что бросается (возможно, перебросить его), и люди будут разумно думать, что catch(Exception) поймал все, но этого не произошло.

К счастью, поскольку .NET 2.0 были более разумными; вы можете положиться на catch {}, catch(Exception) {} и catch(Exception ex) {}, чтобы все поймали все, что вам нужно.

И наконец: если по какой-то сумасшедшей причине вы хотите включить поведение С# 1.0, вы можете поместить

[assembly:System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows = false)]

в вашей программе.

Ответ 3

Первая версия ловит все исключения, происходящие из класса Exception.

Вторая версия ловит указанное исключение.

Третья версия ловит указанное исключение с объявленным именем. Затем в блоке catch вы можете использовать этот объект, например, чтобы увидеть полную ошибку: e.ToString();

Подробнее здесь.

Ответ 4

Все они делают в основном одно и то же, разница заключается в количестве информации, которую они предоставляют об ошибке.

catch (foo ex) {} будет отфильтровывать все исключения, кроме тех, которые могут быть выбраны для ввода foo. Он также дает вам пример ошибки для вас.

catch (foo) {} делает то же, что и выше, но не дает вам экземпляр исключения. Вы узнаете тип исключения, но не сможете прочитать информацию из него.

Обратите внимание, что в обоих случаях, если тип исключения равен Exception, они поймают все исключения.

catch {} ловит все исключения. Вы не знаете тип, который он поймал, и вы не можете получить доступ к экземпляру.

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

Независимо от того, какой из них вы используете, вы можете передать исключенное исключение вперед с помощью команды throw; (без аргументов).

Ответ 5

В вашем примере ничего, потому что вы ничего не делаете с исключением. Но прояснить & hellip;

  • Это улавливает все, но ничего не делает с исключением.

    catch {}
    

    Это полезно, когда вы хотите сказать, что гарантируете возврат из метода.

  • Это улавливает только исключения типа Exception (это все), но ничего не делает с исключением.

    catch (Exception) {}
    

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

  • Это улавливает только исключения типа Exception (это все) и может делать что-то с исключением, но ничего не делает

    catch (Exception ex) {}
    

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

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

Ответ 6

Добавление catch (Exception e) даст вам доступ к объекту Exception, который содержит сведения об исключении, которое было выбрано, например Message и StackTrace; полезно регистрировать эту информацию, чтобы помочь диагностировать ошибки. Простой улов, не объявляющий исключение, которое вы пытаетесь поймать, не даст вам доступ к объекту исключения.

Кроме того, ловить базовое исключение обычно считается плохой практикой, потому что оно слишком универсальное, и, где возможно, вы всегда должны иметь случай для конкретного исключения. Например, если вы работаете с файлами, вы можете рассмотреть следующий блок try/catch:

try{
    //open your file and read/write from it here
}catch(FileNotFoundException fe){
    //log the message
    Log(fe.Message);
}catch(Exception e){
    //you can catch a general exception at the end if you must
}finally{
    //close your file
}

Ответ 7

На самом высоком уровне они все одинаковы; они все ловят исключения.

Но для дальнейшего продолжения, в первом случае вы ловите исключение и ничего не делаете с ним (у вас нет определенного типа). Во втором примере вы перехватываете исключение типа Exception. В последнем примере вы используете тот же тип исключения, что и в примере 2, но теперь вы помещаете исключение в переменную, которая позволит вам показать ее в MessageBox или:

e.Message

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

try {
}
catch (SqlException sqlExc) {
}
catch (Exception exc) {
}