繁体   English   中英

使用“yield”时,为什么编译器生成的类型同时实现IEnumerable和IEnumerator

[英]When using “yield” why does compiler-generated type implement both IEnumerable and IEnumerator

我们正在尝试使用IEnumerable作为工厂,每次迭代时都会生成不同的对象。 那些应该尽快GC。 但请注意,我们保留对枚举器的引用,以便我们可以再次调用它。 所以我们的程序基本上是这样的:

public class YieldSpec
{
    public static IEnumerable<string> Strings()
    {
        yield return "AAA";
        yield return "BBB";
        yield return "CCC";
    } 
    public void YieldShouldAllowGC()
    {
        var e = Strings();
        foreach (var a in e)
        {
            Console.WriteLine(a);
        }

    }
}

在调试器中查看该代码:

在此输入图像描述

您可以看到,当遇到断点时,IEnumerable会引用“CCC”

这不应该真的发生。 IEnumerable应该只在调用GetEnumerator时生成IEnumerator。 这是IEnumerable可以包含状态的预期行为吗?

作为性能原因的实现细节,是的,状态机实现了IEnumerableIEnumerator 也就是说,正确地做到这一点非常聪明。 这是IEnumerable第一次被要求IEnumerator返回它自己。 将来对GetEnumerator任何调用都会导致正在创建的对象的新实例,以便可以维护单独的迭代器状态。 这样做是因为虽然能够IEnumerable创建多个IEnumerators很重要,但绝大多数实际情况只涉及一个正在创建的情况,因此这是针对优化的情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM