Это плохая практика, чтобы вернуться изнутри попробовать поймать, наконец, блок?


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

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

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

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

6 119

6 ответов:

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

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

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

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

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

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

Что на самом деле происходит в попробуйте { возвращение х; }, наконец, { х = значение null; } заявление?

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

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

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

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

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

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

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