所以,這個問題只是問的SO:有人可以解釋這個懶惰的評估代碼嗎?
How to handle an "infinite" IEnumerable?
我的示例代碼:
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,枚舉已經「結束」,但實際上它沒有,但是不應該在鏈接完成之前調用Numbers()轉到Take()?採取的結果是什麼實際上正在枚舉,正確的?但是,如果Numbers沒有完全評估,那麼執行如何執行?
EDIT2:那麼這只是'yield'關鍵字執行的特定編譯器技巧嗎?
是的,但是爲了繼續進行接聽呼叫,Numbers()本身不必進行全面評估嗎?我知道數字本身是一個無限循環。爲什麼添加.Take()會突然停止Numbers的整體評估? – Tejs 2010-04-29 19:24:25
有趣。感謝您的鏈接!這個問題(和代碼)讓我做了雙重考慮,現在我意識到我還有更多要學習Enumerables! – Tejs 2010-04-29 19:37:40