140

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

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

现在这段代码编译得很好并且可以正常工作,但是从 try 块中返回感觉不正确,特别是如果有关联的 finally。

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

4

6 回答 6

179

不,这不是一个坏习惯。放在return有意义的地方可以提高可读性和可维护性,并使您的代码更易于理解。你不应该关心如果遇到语句,finally块将被执行。return

于 2009-01-16T00:38:42.847 回答
23

finally 无论如何都会被执行,所以没关系。

于 2009-01-16T00:34:34.990 回答
16

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

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

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

于 2009-01-16T04:14:28.417 回答
13

这可能会回答你的问题

在 try { return x; 中真正发生了什么?} 最后 { x = null; } 陈述?

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

也就是说,无论如何重组代码可能会更好,这样以后就不会混淆您或其他可能不知道这一点的人。

于 2009-01-16T00:33:27.520 回答
6

功能上没有区别。

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

于 2009-01-16T08:37:48.963 回答
3

在您的示例中,任何一种方式都是等效的,如果编译器生成相同的代码,我什至不会感到惊讶。如果在 finally 块中发生异常,无论将 return 语句放在块中还是在块之外,都会遇到相同的问题。

真正的问题是风格上哪个是最好的。我喜欢把我的方法写成只有一个return语句,这样更容易看到方法的流出,所以我也喜欢把return语句放在最后,这样很容易看出它是方法的结尾以及它返回的内容。

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

于 2009-01-16T01:08:07.373 回答