c# - Enumerator.MoveNext() 的奇怪行为

标签 c# infinite-loop enumerator

有人可以解释为什么这段代码在无限循环中运行吗?为什么 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() on - 匿名类型值的副本。您实际上无法更改匿名类型中的值 - 您所拥有的只是一个可以调用的属性,它将为您提供该值的副本。

如果将代码更改为:

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!" .

关于c# - Enumerator.MoveNext() 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31591238/

相关文章:

c# - 添加到自定义 ActionLink 帮助程序扩展的 htmlAttributes

Java 的 .sort() 方法打破了 while 循环

c# - 您如何设计一个返回(理论上)无限数量项目的枚举器?

ruby - 如何使用枚举器

arrays - 为什么 each_cons 产生数组而不是多个值?

c# - 音符持续时间

c# - SQLite 错误 : The 'DbProviderFactories' section can only appear once per config file (IBM Client Access)

c# - ASP.NET 复合控件向父窗体引发事件

while-loop - 为什么阻塞函数不使用 100% CPU?

javascript - 鼠标移动后无限循环