web-dev-qa-db-ja.com

try catch finallyブロック内から戻るのは悪い習慣ですか?

そこで、今朝、次のようなコードを見つけました。

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

これで、このコードは正常にコンパイルされ、正常に機能しますが、特に関連する最終的なものがある場合は、tryブロック内から戻るのが適切ではないと感じるだけです。

私の主な問題は、最終的に自分自身の例外をスローした場合に何が起こるのですか?返された変数だけでなく、対処する例外もあるので、tryブロック内から戻ることについて他の人がどう思うか知りたいですか?

125
lomaxx

いいえ、それは悪い習慣ではありません。 returnを意味のある場所に置くと、読みやすさと保守性が向上し、コードが理解しやすくなります。 finallyステートメントが検出された場合、returnブロックが実行されるため、気にする必要はありません。

162
Mehrdad Afshari

最終的には何が実行されても、問題ではありません。

17
Ed S.

個人的には、finallyステートメントの前にreturnステートメントを見たくないので、この種のコーディングは避けます。

私の心はシンプルで、物事をかなり直線的に処理します。したがって、ドライランニングのコードを調べると、returnステートメントに到達できれば、その後のすべてが問題になることはないと思う傾向があります。副作用が何である可能性があります)。

したがって、returnステートメントが常にfinallyステートメントの後に表示されるようにコードを配置します。

14
Conrad

これはあなたの質問に答えるかもしれません

try {return x;} finally {x = null;}ステートメントで実際に起こることは何ですか?

その質問を読むと、例外をスローする可能性があると思われる場合、finallyステートメントに別のtry catch構造を持つことができるように思えます。コンパイラは、いつ値を返すかを判断します。

とはいえ、コードを再構築する方が、後で混乱したり、これに気付いていない人を混乱させたりしないようにする方が良いかもしれません。

9
Spencer Ruport

機能的には違いはありません。

ただし、これを行わない理由が1つあります。いくつかの出口点を持つ長いメソッドは、多くの場合、読み取りと分析がより困難です。しかし、その異議は、catchおよびfinallyブロックよりも、returnステートメントに関係しています。

4
Ifeanyi Echeruo

あなたの例ではどちらの方法も同等ですが、コンパイラが同じコードを生成したとしても驚かないでしょう。 finallyブロックで例外が発生した場合、returnステートメントをブロック内に配置しても外部に配置しても、同じ問題が発生します。

本当の質問は、スタイル的に最適です。 returnステートメントが1つだけになるようにメソッドを記述するのが好きです。この方法では、メソッドからのフローが見やすくなります。したがって、returnステートメントを最後に配置して、メソッドの終わりとこれが返すもの。

Returnステートメントが最後のステートメントとしてきちんと配置されているため、他のメソッドは来てメソッドの別の部分に複数のreturnステートメントを振りかける可能性が低くなります。

3
BeWarned