栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

错误原因CS0161:并非所有代码路径都返回一个值

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

错误原因CS0161:并非所有代码路径都返回一个值

原因很简单,编译器必须能够 静态验证 所有执行流路径 是否 以return语句(或异常)结尾。

让我们看看您的代码,其中包含:

  • 一些控制
    while
    循环的变量
  • while
    环,与
    return
    声明嵌入式
  • 循环
    return
    语句 __

因此,基本上,编译器必须验证以下内容:

  1. 这在
    while
    实际执行环
  2. return
    语句 始终 执行
  3. 总是抛出一些异常。

编译器根本无法验证这一点。

让我们尝试一个非常简单的示例:

public int Test(){    int a = 1;    while (a > 0)        return 10;}

这个简单的示例将产生完全相同的错误:

CS0161’Test()’:并非所有代码路径都返回一个值

因此,由于以下事实,编译器无法推断出这一点:

  • a
    是一个局部变量(意味着只有局部代码可以影响它)
  • a
    初始值为
    1
    ,并且永不更改
  • 如果
    a
    变量大于零(它是),
    return
    则到达该语句

那么代码将始终返回值10。

现在看这个例子:

public int Test(){    const int a = 1;    while (a > 0)        return 10;}

唯一的区别是我做

a
了一个
const
。现在可以编译了,但这是因为优化器现在可以删除整个循环,最终的IL就是这样:

Test:IL_0000:  ldc.i4.s    0A IL_0002:  ret

整个

while
循环和局部变量都消失了,剩下的就是这个:

return 10;

因此很明显,编译器在静态分析这些内容时不会查看变量值。实施并正确实现此功能的成本可能会超过不执行此操作所带来的影响或负面影响。请记住,“每个功能在漏洞中的起点都是100点,这意味着它必须对整个程序包产生显着的净积极影响,才能使其成为语言。”

所以是的,这绝对是您比编译器更了解代码的情况。


为了完整起见,让我们看一下代码可以流动的所有方式:

  1. maxAttempts
    小于1 可以提前退出
  2. 由于为1且至少为1,因此 它将 进入
    while
    -loop 。
    attempt``maxAttempts
  3. 如果里面的代码
    try
    语句抛出一
    HttpRequestException
    attempt
    递增,如果仍然小于或等于
    maxAttempts
    while
    -loop会做另一次迭代。如果现在大于
    maxAttempts
    该异常,则会冒泡。
  4. 如果引发了其他异常,它将不会得到处理,并且会冒出该方法
  5. 如果没有抛出异常,则返回响应。

因此,基本上可以说,此代码总是以抛出异常或返回为最终结果,但是编译器无法静态验证此结果。


由于您已经将逃逸阴影(

attempt > maxAttempts
)嵌入了两个位置,这两个位置均作为
while
-loop
的标准,并且另外在该
catch
块内,因此我只需将其从
while
-loop中删除即可简化代码:

while (true){    ...        if (attempt > maxAttempts) throw;    ...}

由于可以确保

while
至少运行一次-loop,并且实际上它将是
catch
退出该循环的块,因此只需对它进行形式化即可使编译器再次感到满意。

现在,流控制如下所示:

  • while
    循环将 一直 执行(或者我们已经抛出的异常)
  • while
    循环将 永远不会 终止(无
    break
    里面,所以在循环之后不需要任何代码)
  • 退出循环的唯一可能方法是显式
    return
    或异常,编译器都无需再验证它们,因为此特定错误消息的重点是标记有可能存在一种无需显式的方法来逃逸该方法的方法。
    return
    。由于无法避免方法的意外退出,因此可以简单地跳过其余​​检查。

即使此方法也可以编译:

    public int Test(){    while (true)    {    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/392869.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号