だから、この質問はちょうどSOで尋ねられました:
私のサンプルコード:
public static void Main(string[] args)
{
foreach (var item in Numbers().Take(10))
Console.WriteLine(item);
Console.ReadKey();
}
public static IEnumerable<int> Numbers()
{
int x = 0;
while (true)
yield return x++;
}
誰かがこれが遅延評価される理由を説明できますか?私はReflectorでこのコードを調べましたが、始めたときよりも混乱しています。
リフレクター出力:
public static IEnumerable<int> Numbers()
{
return new <Numbers>d__0(-2);
}
数値メソッドの場合、その式の新しい型を生成したように見えます。
[DebuggerHidden]
public <Numbers>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
}
これは私には意味がありません。そのコードをまとめて自分で実行するまでは、無限ループだと思っていたでしょう。
編集:これで、.Take()は、列挙が「終了」したことをforeachに伝えることができますが、実際には終了していないのに、Take()にチェーンする前にNumbers()全体を呼び出すべきではないことを理解しました。 ?テイクの結果は、実際に列挙されているものですよね?しかし、Numbersが完全に評価されていない場合、Takeはどのように実行されますか?
EDIT2:では、これは「yield」キーワードによって強制される特定のコンパイラトリックですか?