有人可以解释为什么此代码在无限循环中运行吗?为什么MoveNext()
总是返回true
?
var x = new { TempList = new List<int> { 1, 3, 6, 9 }.GetEnumerator() };
while (x.TempList.MoveNext())
{
Console.WriteLine("Hello World");
}
最佳答案
List<T>.GetEnumerator()
返回可变值类型( List<T>.Enumerator
)。您正在以匿名类型存储该值。
现在,让我们看一下它的作用:
while (x.TempList.MoveNext())
{
// Ignore this
}
这等效于:
while (true)
{
var tmp = x.TempList;
var result = tmp.MoveNext();
if (!result)
{
break;
}
// Original loop body
}
现在,请注意我们在调用
MoveNext()
的方式-匿名类型中值的副本。您实际上无法更改匿名类型中的值-您所拥有的只是一个可以调用的属性,它将为您提供该值的副本。如果将代码更改为:
var x = new { TempList = (IEnumerable<int>) new List<int> { 1, 3, 6, 9 }.GetEnumerator() };
...然后您将最终获得匿名类型的引用。对包含可变值的框的引用。当您在该引用上调用
MoveNext()
时,该框内的值将发生突变,因此它将执行您想要的操作。有关非常相似情况的分析(再次使用
List<T>.GetEnumerator()
),请参见my 2010 blog post "Iterate, damn you!"。