Чи погана практика повернутися зсередини блоку спробувати?


128

Тому я наткнувся на якийсь код цього ранку, який виглядав приблизно так:

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

Тепер цей код чудово компілюється і працює як слід, але повертатися з блоку спробу просто не вважається правильним, особливо якщо там нарешті пов'язано.

Моє головне питання - що станеться, якщо нарешті викине власний виняток? У вас є повернута змінна, але також виняток, з яким потрібно боротися ... тому мені цікаво знати, що думають інші про повернення з пробного блоку?


13
Однією з переваг цього стилю є те, що вам не потрібно декларувати xпоза tryблоком. Ви можете зберігати його декларацію близько до використання.
David R Tribble

Відповіді:


169

Ні, це не погана практика. Розміщення returnтам, де це має сенс, покращує читабельність та ремонтопридатність та робить ваш код простішим для розуміння. Вам не варто піклуватися про те, що finallyблок буде виконуватися, якщо виникає returnзаява.


19

Нарешті буде виконано незалежно від того, тому це не має значення.


9
Ні, насправді це не просто підключення, є деякі винятки, які називаються винятками з асинхронізацією, наприклад StackOverflowException, ThreadAbortException та OutOfMemoryException, які можуть призвести до того, що блок нарешті не буде виконаний. Прочитайте про обмежені регіони виконання для обробки цих сценаріїв.
Мехрдад Афшарі


14

Особисто я би уникав такого кодування, оскільки не відчуваю, як бачити зворотні заяви перед нарешті.

Мій розум простий і він обробляє речі досить лінійно. Тому коли я переходжу до коду для сухого запуску, у мене буде схильність думати, що як тільки я можу дійти до заяви про повернення, все, що випливає, не має значення, що, очевидно, в цьому випадку досить неправильно (не те, що це вплине на заяву повернення, але які побічні ефекти можуть бути).

Таким чином, я впорядкував би код так, щоб твердження про повернення завжди з'являлося після остаточних тверджень.


9

Це може відповісти на ваше запитання

Що насправді відбувається при спробі {return x; } нарешті {x = null; } заява?

Якщо прочитати це запитання, то, здається, ви можете мати ще одну структуру спробувати вловлювання, нарешті, якщо ви думаєте, що це може спричинити виняток. Компілятор визначить, коли потрібно повернути значення.

З огляду на це, може бути краще все-таки реструктурувати свій код, щоб він не плутав вас згодом або когось іншого, хто також може про це не знати.


хммм, дуже цікаво. Це означає, що це безпечно, але чи означає це, що його слід уникати?
lomaxx

3
Особисто я вважаю, що це робить читабельність вашого коду трохи важкою, і цього лише було б достатньо, щоб я міг зрозуміти якийсь інший спосіб структурування коду. Але насправді це лише особисті переваги.
Спенсер Рупорт

3
Я схильний погоджуватися з вашими особистими уподобаннями :)
lomaxx

Я думаю, що повернення добре там, де воно є. Метод поверне значення, якщо не буде викинуто виняток; не має значення, якщо виняток виникає в остаточному коді очищення.
Лоуренс Дол

Зверніть увагу , що обмеження по поверненню з остаточно НЕ присутній в Java (але я думаю , що обмеження є хорошою один - престижність C #).
Лоуренс Дол

5

Функціонально різниці немає.

Однак є одна причина цього не робити. Більш тривалі методи з декількома точками виходу часто важче читати та аналізувати. Але це заперечення має більше спільного з твердженнями про повернення, ніж улов і, нарешті, блокує.


Я б заперечував цим, оскільки ви могли б створити більше гніздування, що також ускладнює читання вищої цикломатичної складності
matt_lethargic

3

У вашому прикладі будь-який спосіб рівнозначний, я навіть не здивувався, якби компілятор створив той самий код. Якщо виняток трапляється у блоці, нарешті, у вас є ті самі проблеми, якщо ви ставите команду return у блок або поза ним.

Справді питання стилістично, що найкраще. Мені подобається писати свої методи, щоб було лише одне твердження повернення; таким чином легше бачити витік методу, звідси випливає, що я також люблю ставити зворотній вислів останнім, тому легко зрозуміти, що це кінець методу і це те, що він повертає.

Я думаю, що із заявою return так чітко розміщено, як і останнє, інші шанси на те, що інші приходять і розповсюджують кілька заяв про повернення в інші частини методу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.