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


128

だから今朝、次のようなコードに出くわしました。

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

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

私の主な問題は、がそれ自身の例外を最終的にスローするとどうなるかです。あなたは返された変数を持っていますが、処理する例外も持っています...だから私は他の人がtryブロック内から戻ることについてどう思うか知りたいですか?


13
このスタイルの1つの利点はxtryブロックの外側で宣言する必要がないことです。宣言を使用に近づけることができます。
David R Tribble

回答:


169

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


19

finallyは何があっても実行されるため、関係ありません。


9
いいえ、実際には、プラグインだけではありません。StackOverflowException、ThreadAbortException、OutOfMemoryExceptionなどの非同期例外と呼ばれるいくつかの例外があり、finallyブロックが実行されない可能性があります。これらのシナリオを処理するための制約付き実行領域についてお読みください。
Mehrdad Afshari、

これらのリンクはそれを説明しています:returnステートメントtry ... catch ... finallyステートメント
amit jha

14

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

私の心は単純で、物事を直線的に処理します。したがって、ドライランのコードをウォークスルーするとき、returnステートメントに到達すると、すべてがこの問題で明らかに間違っていることは問題ではないと考える傾向があります(returnステートメントに影響するわけではありませんが、副作用は何であるか)。

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


9

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

try {return x;で実際に何が起こるか }最後に{x = null; }ステートメント?

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

とはいえ、とにかくコードを再構築して、後であなたやこのことを知らない誰かを混乱させないようにした方がいいかもしれません。


うーん、とても面白い。つまり、それは安全だということですが、それは避けなければならないということですか?
lomaxx 2009年

3
個人的にはコードの可読性が少し難しくなると思いますが、それだけでコードを構造化する他の方法を理解するには十分でしょう。しかし、実際にはそれは個人的な好みです。
スペンサールポート2009年

3
私はあなたの個人的な好みに同意する傾向があります:)
lomaxx 2009年

返品はどこでも結構だと思います。例外がスローされない限り、メソッドは値を返します。最終的にクリーンアップするコードで例外が発生しても問題ありません。
Lawrence Dol、

finallyからの復帰に関する制限はJavaに存在しないことに注意してください(ただし、この制限は良いものだと思います-C#への称賛)。
Lawrence Dol、

5

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

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


入れ子が多くなり、より高い循環的複雑度を読み取ることが難しくなる可能性があるので、これに挑戦します
matt_lethargic

3

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

本当の質問は、文体的にどちらが良いかです。returnステートメントが1つだけになるようにメソッドを書くのが好きです。これにより、メソッドからのフローが見やすくなり、returnステートメントを最後に置いて、メソッドの終わりとこれが返すもの。

最後のステートメントとして整然と配置されたreturnステートメントを使用すると、他のユーザーが来て、メソッドの他の部分に複数のreturnステートメントを振りかける可能性が低くなると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.