有人可以解释为什么此代码在无限循环中运行吗?为什么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!"

09-26 20:33