关于c#:从try catch finally块中返回是不好的做法?

Is it bad practice to return from within a try catch finally block?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
try
{
    x = SomeThingDangerous();
    return x;
}
catch (Exception ex)
{
    throw new DangerousException(ex);
}
finally
{
    CleanUpDangerousStuff();
}

现在,这段代码编译得很好,可以正常工作,但是从一个try块中返回是不合适的,特别是在有关联的finally的情况下。

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


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


不管怎样,最后都会被执行,所以没关系。


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

我的头脑很简单,它对事物的处理相当线性。因此,当我浏览干运行的代码时,我会倾向于认为,一旦我能够到达返回语句,后面的所有内容都不重要,在这种情况下,这显然是非常错误的(不是它会影响返回语句,而是会有什么副作用)。

因此,我将对代码进行排列,以便返回语句始终出现在finally语句之后。


这可以回答你的问题

try return x;finally x=null;语句中实际发生了什么?

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

这就是说,不管怎样,重新构造代码可能会更好,这样以后就不会混淆您或其他不知道这一点的人。


功能上没有区别。

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


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

真正的问题是在风格上哪一个最好。我喜欢编写我的方法,这样就只有一个返回语句,这样就更容易看到方法的流,这就意味着我也喜欢将返回语句放在最后,这样就很容易看到它是方法的结尾,这就是它返回的内容。

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