如何处理“;并不是所有的代码路径都返回一个值“0”;当函数的逻辑确实确保返回时
本文关键字:返回 函数 确保 一个 并不是 处理 何处理 路径 代码 | 更新日期: 2023-09-27 18:28:59
我想最简单的解释方法是通过一个人为的例子:
public static int Fail() {
var b = true;
if (b) {
return 0;
}
}
这段代码不会编译,并给出错误"并非所有代码路径都返回值",而我们人类可以清楚地看到这一点。我确实理解为什么。我的问题是应该采取什么措施来补救这种情况。可能是这样的:
public static int Fail() {
var b = true;
if (b) {
return 0;
}
throw new ApplicationException("This code is unreachable... but here we are.");
}
但这一切似乎都很愚蠢。有更好的方法吗?同样,这段代码是一个精心设计的示例(可以简化为return 0
)。我的实际代码是庞大而复杂的,但在尝试退出之前,确实会从逻辑上(通过数学证明)返回一个值。
C#代码流分析是有限的,正如您的示例所指出的,在某些情况下,所有路径都会返回,但编译器无法检测到。在这种情况下,抛出异常是可以接受的补救措施。
我不会使用默认值的返回来修复这个错误。您是在这样一种假设下操作的,即该行永远不会违反编译器的建议。请考虑一下您的分析是错误的,执行可以继续到方法的末尾。如果您返回一个默认值,那么您将没有问题的迹象。该方法只会返回错误的数据。抛出异常会使问题变得非常明显。
然而,在这些情况下,我倾向于简单地重写代码,这样编译器就可以看到所有路径都终止了。总的来说,我发现如果这个方法太复杂了,编译器无法遵循它,那么在我之后拿起代码的人也无法遵循它。
我认为您当前的方法是正确的。在方法末尾返回默认值是有风险的,因为如果逻辑中存在流,则可能会到达此指令,这可能会产生意外的后果。如果你抛出一个异常,它会给你一个发现错误的机会。
编译器不会执行复杂的数学过程来确保返回值,在这方面它是一个相对愚蠢的野兽。
如果你确信自己的假设,只需在末尾添加return 0;
,并附上一条说明现实的评论,即永远无法实现。
当然,任何可以保证最终条件为true的代码都可以删除该条件,正如您已经说过的那样。即使在复杂的情况下,这在数学上也是正确的。因此,您可以重构代码以考虑,而不需要多余的返回。
通常有几个程序员类:
- 他们到处都回来了
- 它们只在函数/方法结束时返回
第一种方法:
public static int Fail() {
var b = true;
if (b)
return 0;
return 1;
}
我通常更喜欢第二种方法,因为它更容易快速查看函数/方法的返回位置。
public static int Fail() {
var b = true;
var returnValue = 1:
if (b)
returnValue = 0;
return returnValue;
}
答案真的很晚,但我可以想象函数不知道返回什么的场景:
1) 使用调试器逐步运行
2) 跨过var b = true;
3) 当达到if (b) {
时,将b = false
放入手表。它将返回false
并分配b = false
4) 跨步(通过if
)
5) 功能结束,没有返回
从这个角度来看,显然需要return
。
我有这样的代码,并用这种方式修复了它。看看你的例子:
public static int Fail() {
var b = true;
if (b) {
return 0;
}
throw new ApplicationException("This code is unreachable... but here we are.");
}
将成为
public static int Fail() {
var b = true;
if (!b) {
throw new ApplicationException("This code is unreachable... but here we are.");
}
return 0;
}
这将消除编译器警告,在逻辑上仍然相同,并且实际上是稍微干净的代码。