所以,这个问题只是被问到了:
我的示例代码:
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);
}
对于 numbers 方法,并且看起来已经为该表达式生成了一个新类型:
[DebuggerHidden]
public <Numbers>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId;
}
这对我来说毫无意义。在我将代码放在一起并自己执行之前,我会认为这是一个无限循环。
编辑:所以我现在明白 .Take() 可以告诉 foreach 枚举已经“结束”,而实际上它还没有,但在链接到 Take() 之前不应该完整地调用 Numbers() ? Take 结果是实际枚举的结果,对吗?但是,当 Numbers 没有完全评估时,Take 是如何执行的呢?
EDIT2:那么这只是'yield'关键字强制执行的特定编译器技巧吗?