Почему решарпер говорит: «Предложение Catch с одним оператором throw избыточно»?

StackOverflow https://stackoverflow.com/questions/1019237

Вопрос

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

Почему Решарпер говорит, что это избыточно?

try
{
    File.Open("FileNotFound.txt", FileMode.Open);
}
catch
{
    throw;
}
Это было полезно?

Решение

Потому что

try {
    File.Open("FileNotFound.txt", FileMode.Open);
} catch {
    throw;
}

ничем не отличается от

File.Open("FileNotFound.txt", FileMode.Open);

Если вызов на File.Open(string, FileMode) терпит неудачу, то в любом примере одно и то же исключение попадет в пользовательский интерфейс.

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

Однако,

try {
    File.Open("FileNotFound.txt", FileMode.Open);
} catch(Exception ex) {
    GetLogger().LogException(ex);
    throw;
}

не будет содержать никаких избыточностей, и ReSharper не должен жаловаться.Так же,

try {
    File.Open("FileNotFound.txt", FileMode.Open);
} catch(Exception ex) {
    throw new MyApplicationException(
        "I'm sorry, but your preferences file could not be found.", ex);
}

не будет лишним.

Другие советы

Потому что вышеупомянутое утверждение ведет себя так же, как если бы его не было. То же, что и письмо:

File.Open("FileNotFound.txt", FileMode.Open);

Поскольку код в попытке уже генерирует исключение.

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

Потому что это избыточно.

Вы не выполнили никакой обработки в блоке catch, просто снова сгенерировали исключение.

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

Кроме того, еще один полезный совет: «Брось ex» не сохранит трассировку стека, но "throw" будет.

Стоит отметить, что пока ...

try
{
    DoSomething();
}
catch
{
    throw;
}

... является избыточным, следующее не является ...

try
{
    DoSomething();
}
catch (Exception ex)
{
    // Generally a very bad idea!
    throw ex;
}

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

Удачи, отладочный код, который делает это!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top