Это плохая практика, чтобы вернуться из блока try catch catch finally? - PullRequest
125 голосов
/ 16 января 2009

Итак, сегодня утром я наткнулся на какой-то код, который выглядел так:

try
{
    x = SomeThingDangerous();
    return x;
}
catch (Exception ex)
{
    throw new DangerousException(ex);
}
finally
{
    CleanUpDangerousStuff();
}

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

Моя главная проблема в том, что произойдет, если, наконец, выбрасывает свое собственное исключение? У вас есть возвращенная переменная, но также есть исключение, с которым нужно иметь дело ... поэтому мне интересно узнать, что другие думают о возвращении из блока try?

Ответы [ 6 ]

161 голосов
/ 16 января 2009

Нет, это не плохая практика. Помещение return туда, где это имеет смысл, улучшает читабельность и удобство обслуживания и делает ваш код более простым для понимания. Вас не должно волновать, что блок finally будет выполнен, если встретится оператор return.

17 голосов
/ 16 января 2009

Наконец будет выполнено, несмотря ни на что, поэтому это не имеет значения.

14 голосов
/ 16 января 2009

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

Мой разум прост и обрабатывает вещи довольно линейно. Поэтому, когда я прохожу код для пробного запуска, у меня будет склонность думать, что, как только я доберусь до оператора return, все последующее не имеет значения, что, очевидно, в данном случае довольно неправильно (не то, что это повлияет на оператор return, но какие побочные эффекты могут быть).

Таким образом, я бы расположил код так, чтобы оператор return всегда появлялся после операторов finally.

9 голосов
/ 16 января 2009

Это может ответить на ваш вопрос

Что на самом деле происходит при попытке {return x; } наконец {х = ноль; } заявление?

После прочтения этого вопроса звучит так, как будто вы можете иметь другую структуру try catch в операторе finally, если считаете, что она может вызвать исключение. Компилятор определит, когда возвращать значение.

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

4 голосов
/ 16 января 2009

Функционально разницы нет.

Однако есть одна причина не делать этого. Более длинные методы с несколькими точками выхода часто труднее читать и анализировать. Но это возражение больше относится к операторам return, чем к catch и, наконец, к блокам.

3 голосов
/ 16 января 2009

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

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

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

...