C# - 如何创建不可检测的无限循环?

时间:2010-02-22 18:29:34

标签: c# loops infinite-loop

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

在C#-in-depth中Jon Skeet谈到lambda表达式:
“如果存在非空返回类型,则每个代码路径都必须返回兼容值。”(页243)

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

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

这可以仅通过逻辑来完成吗?或者是通过使用数据库或文件系统等外部因素来完成的?

2 个答案:

答案 0 :(得分: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节。

答案 1 :(得分: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());