13

これは単なる「私は好奇心が強い」質問です。

C#の詳細で、Jon Skeetはラムダ式について次のように述べて
います。「非voidの戻り型がある場合、すべてのコードパスは互換性のある値を返す必要があります。」(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 * 0がゼロではないxの値があるかもしれないので、ブレークに到達できるので、これは無限ループではありません」と言います。あなたと私は、数学を知っているのでこれが不可能であることを知っていますが、コンパイラはそうではありません。

詳細が必要な場合は、セクション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 に答える