.net Exception catch блок - PullRequest
       21

.net Exception catch блок

10 голосов
/ 18 марта 2011

В чем разница между следующими блоками перехвата?

try
{
    ...
}
catch
{
    ...
}

и

try
{
    ...
}
catch(Exception)
{
    ...
}

Я понимаю, что в любом случае экземпляр исключения недоступен, но есть что-томожно сделать с одним, что невозможно с другим?

Ответы [ 6 ]

7 голосов
/ 18 марта 2011

catch без аргументов будет перехватывать не совместимые с CLS исключения, в отличие от catch (Exception).

7 голосов
/ 18 марта 2011

Они почти одинаковы.

Из спецификации языка C #, раздел 8.10:

Некоторые языки программирования могут поддерживать исключения, которые не могут быть представлены какобъект, полученный из System.Exception, хотя такие исключения никогда не могут быть сгенерированы кодом C #.Для вылова таких исключений может использоваться общее условие catch.Таким образом, общее предложение catch семантически отличается от предложения, которое указывает тип System.Exception, в том, что первое также может перехватывать исключения из других языков.

Обратите внимание, что, хотя C # различает два, онифактически совпадают с .NET 2.0, как отмечает этот блог :

Благодаря недавнему изменению в 2.0 CLR, если у вас был код, который решил выбросить,скажем, int (System.Int32) где-нибудь, CLR теперь обернет его с помощью RuntimeWrappedException, и компилятор был обновлен, чтобы дать вам предупреждение о том, что второе приведенное выше предложение теперь является мертвым кодом

warning CS1058: A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException

Для того, как CLR знает, как выполнить это действие для вашей сборки, вы заметите, что компилятор теперь добавляет атрибут RuntimeCompatibilityAttribute в ваши сборки, сообщая ему:
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = {property bool 'WrapNonExceptionThrows' = bool(true)}

4 голосов
/ 18 марта 2011

С Почему улов (Исключение) / пустой улов плох

Пустые операторы улова могут быть такими же плохими, в зависимости от кода MSIL, который генерирует ваш язык. C # превращает пустой оператор catch в catch (System.Object), что означает, что вы в конечном итоге перехватываете все исключения - даже исключения, не совместимые с CLS .VB ведет себя лучше, превращая пустой оператор catch в catch e как System.Exception, который ограничивает вас перехватом исключений, соответствующих CLS.

3 голосов
/ 18 марта 2011

Если вы посмотрите на сгенерированный IL, вот разница:

catch(Exception){}:

catch [mscorlib]System.Exception
{}

и просто улов:

catch{}:

catch [mscorlib]System.Object
{}

Теоретически, если вы создаете язык, который может иметь исключенияНЕ наследовать от System.Exception, будет разница ...

1 голос
/ 18 марта 2011

Языки, не связанные с CLS (например, C ++ / CLI), могут генерировать объекты, не производные от класса System.Exception.Первый пример кода позволит вам выполнить код в блоке catch, хотя вы не можете проверить сам брошенный объект.Это почти никогда не проблема, но это может быть.

0 голосов
/ 18 марта 2011

Я не верю, что есть разница, и такой инструмент, как Resharper, скажет вам, что catch(Exception) является избыточным во втором случае, ЕСЛИ вы не вставили другие catch(SomeSubclassException) блоки обработки исключений перед Exception для применениядругая логика обработки исключений для других условий исключений.

...