Enumerator.MoveNext() 的奇怪行为

2024-02-04

有人可以解释为什么这段代码在无限循环中运行吗?为什么MoveNext() return true always?

var x = new { TempList = new List<int> { 1, 3, 6, 9 }.GetEnumerator() };
while (x.TempList.MoveNext())
{
  Console.WriteLine("Hello World");
}

List<T>.GetEnumerator() https://msdn.microsoft.com/en-us/library/b0yss765返回一个可变值类型(List<T>.Enumerator https://msdn.microsoft.com/en-us/library/x854yt9s)。您将该值存储在匿名类型中。

现在,让我们看看它的作用:

while (x.TempList.MoveNext())
{
    // Ignore this
}

这相当于:

while (true)
{
    var tmp = x.TempList;
    var result = tmp.MoveNext();
    if (!result)
    {
        break;
    }

    // Original loop body
}

现在请注意我们所说的MoveNext()在 - 上copy匿名类型中的值。您实际上无法更改匿名类型中的值 - 您所拥有的只是一个可以调用的属性,它将为您提供该值的副本。

如果将代码更改为:

var x = new { TempList = (IEnumerable<int>) new List<int> { 1, 3, 6, 9 }.GetEnumerator() };

...然后你最终会得到一个参考在匿名类型中。对包含可变值的框的引用。你打电话时MoveNext()在该引用上,框中的值将发生变化,因此它将执行您想要的操作。

用于分析非常相似的情况(再次使用List<T>.GetEnumerator()) see 我 2010 年的博客文章“迭代,该死的!” http://codeblog.jonskeet.uk/2010/07/27/iterate-damn-you/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Enumerator.MoveNext() 的奇怪行为 的相关文章

随机推荐