从 try catch finally 块中返回是不是不好的做法?

我今天早上偶然发现了一些代码,看起来像这样:

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

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

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

78318 次浏览

这也许能回答你的问题

在 try { return x; } finally { x = null; }语句中到底发生了什么?

从阅读这个问题来看,如果您认为 finally 语句可能会抛出异常,那么似乎可以在这个语句中使用另一个 try catch 结构。编译器将确定何时返回值。

也就是说,最好还是重新构造代码,这样以后就不会让您或其他可能不知道这一点的人感到困惑。

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

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

在您的示例中,无论哪种方式都是等价的,如果编译器生成相同的代码,我甚至不会感到惊讶。如果 finally 块中发生异常,则无论是将 return 语句放在 block 中还是放在其外部,都会遇到相同的问题。

真正的问题在于文体上哪一个是最好的。我喜欢把方法写成只有一个 return 语句,这样更容易看到方法的流程,因此我也喜欢把 return 语句放在最后,这样很容易看到它是方法的结束,这就是它返回的结果。

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

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

我的头脑很简单,处理事情的方式也很线性。因此,当我浏览返回语句的代码时,我会倾向于认为,一旦我能够到达 return 语句,接下来的所有事情都不重要了,在这种情况下,哪一个显然是错误的(不是说它会影响 return 语句,而是它的副作用可能是什么)。

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

在功能上没有区别。

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