13

这只是一个“我很好奇”的问题。

在深入 C# 中,Jon Skeet 谈到了 lambda 表达式:
“如果有一个非空返回类型,那么每个代码路径都必须返回一个兼容的值。” (第 233 页)

脚注然后说:
“当然,抛出异常的代码路径不需要返回值,可检测的无限循环也不需要。” (第 233 页)

我想知道什么构成不可检测的无限循环?

这只能通过逻辑来完成吗?还是通过使用数据库或文件系统等外部因素来完成?

4

2 回答 2

21

Jon 所指的内容在规范的第 8.1 节中进行了描述。编译器只能检测到非常简单的无限循环,例如:

while(true) { if (0 != 0) return 123; }

编译器足够聪明,可以看到永远不会达到返回值,因此循环会永远运行。这是合法的,虽然很疯狂,说:

int M() { while(true) { } }

因为虽然没有返回 int 的路径,但也没有返回返回 int 的路径!

编译器不够聪明,无法找到其他类型的无限循环。例如:

int x = 123;
while(true) { if (x * 0 != 0) break; }

这显然是一个无限循环。但是编译器不知道这一点。编译器说“好吧,也许有一些 x 的值,其中 x * 0 不为零,所以中断是可以到达的,所以这不是无限循环”。你我都知道这是不可能的,因为我们知道数学,但编译器不知道。

如果您想了解详细信息,请阅读第 8.1 节。

于 2010-02-22T19:01:40.547 回答
3

使用外部资源甚至滥用接口等工具来创建无限循环非常简单。

例如:

  public interface INumbers
    {
        int GetNumber(int arg);
    }
    public class StaticNumber : INumbers
    {
        public int GetNumber(int arg)
        {
            return 1;
        }
    }
    public void DoStuff(INumbers num)
    {
        int i = 42;
        while ((i = num.GetNumber(i)) != 0)
        {
            ;
        }
    }

然后一个简单的

Action action = () => DoStuff(new StaticNumber());
于 2010-02-22T18:40:54.183 回答