从try catch最终阻止中返回是否是错误的做法?


128

所以今天早上我遇到了一些看起来像这样的代码:

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

现在,此代码可以正常编译并且可以正常工作,但是从try块中返回并不适合,特别是如果有关联的final。

我的主要问题是,如果最终抛出了自己的异常,将会发生什么?您有一个返回的变量,但也有一个异常要处理...所以我想知道其他人如何从try块中返回?


13
这种样式的一个好处是您不必xtry块外声明。您可以使其声明接近使用。
David R Tribble

Answers:


169

不,这不是一个坏习惯。将return其放在合理的位置可以提高可读性和可维护性,并使您的代码更易于理解。您不必担心,finally如果return遇到语句,块将被执行。


19

无论如何,finally都将执行,所以没有关系。


9
不,实际上,这不仅仅是插入,还有一些称为异步异常的异常,例如StackOverflowException,ThreadAbortException和OutOfMemoryException,它们可能导致无法执行finally块。阅读有关用于处理这些方案的受限执行区。
Mehrdad Afshari,2009年

这些链接对此进行了解释:返回语句尝试...捕获...最终语句
amit jha

14

就我个人而言,我会避免这种编码,因为我不希望在finally语句之前看到return语句。

我的想法很简单,它以线性方式处理事物。因此,当我遍历代码进行空运行时,我会倾向于认为,一旦我可以到达return语句,那么紧随其后的一切都无关紧要,这在这种情况下显然是非常错误的(不是因为这会影响return语句,而是可能会有什么副作用)。

因此,我将安排代码,以便return语句始终出现在finally语句之后。


9

这可能会回答您的问题

尝试实际发生的情况{return x; }最后{x = null; }语句?

通过阅读该问题,听起来如果您认为它可能引发异常,那么您可以在finally语句中具有另一个try catch结构。编译器将确定何时返回该值。

也就是说,最好还是重新组织代码,以免以后再引起您或其他可能也没有意识到这一点的人感到困惑。


嗯,很有趣。这意味着它很安全,但这是否意味着应该避免它?
lomaxx

3
就我个人而言,我认为这会使代码的可读性变得有些困难,仅此一项就足以让我弄清楚构造代码的其他方式。但这实际上只是个人喜好。
斯宾塞·鲁波特

3
我倾向于同意您的个人喜好:)
lomaxx

我认为回报是可以的。该方法将返回该值,除非抛出异常。最终清理代码中是否出现异常并不重要。
劳伦斯·多尔

请注意,Java中存在对从finally返回的限制(但是我认为该限制是一个不错的选择-对C#表示敬意)。
劳伦斯·多尔

5

在功能上没有区别。

但是,没有这样做的原因之一。具有多个出口点的较长方法通常更难以阅读和分析。但是,该异议更多地与return语句有关,而不是catch和finally块。


我会对此提出挑战,因为您最终可能会有更多的嵌套,这也使得阅读更高的圈复杂度变得更加困难
matt_lethargic

3

在您的示例中,这两种方法都是等效的,即使编译器生成相同的代码,我也不会感到惊讶。如果在finally块中发生异常,则无论将return语句放在块中还是在块外,都将遇到相同的问题。

从造型上看,真正的问题是最好的。我喜欢编写自己的方法,以便只有一个return语句,这样更容易看到方法的流程,因此,我也喜欢将return语句放在最后,因此很容易看出它是方法的结尾及其返回的内容。

我认为return语句与最后一条语句一样整齐,其他人不太可能将多个return语句散布到方法的其他部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.