c# - yield 是如何枚举的?

标签 c# ienumerable yield-return

我在玩弄 yieldIEnumerable我现在很好奇以下代码片段为何或如何工作:

public class FakeList : IEnumerable<int>
{
    private int one;
    private int two;

    public IEnumerator<int> GetEnumerator()
    {
        yield return one;
        yield return two;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

现在编译器如何转换它:

public IEnumerator<int> GetEnumerator()
{
    yield return one;
    yield return two;
}

进入IEnumerator<int>

最佳答案

使用 yield return 时,编译器会为您生成一个枚举器类。所以实际使用的代码比仅仅两个 return 语句要复杂得多。编译器添加所有必要的代码来为您返回一个枚举器,它迭代 yield return 的结果。 .


这是从您的 FakeList.GetEnumerator() 生成的代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;

public class FakeList : IEnumerable<int>, IEnumerable
{
    private int one;
    private int two;

    [IteratorStateMachine(typeof(<GetEnumerator>d__2))]
    public IEnumerator<int> GetEnumerator()
    {
        yield return this.one;
        yield return this.two;
    }

    IEnumerator IEnumerable.GetEnumerator() => 
        this.GetEnumerator();

    [CompilerGenerated]
    private sealed class <GetEnumerator>d__2 : IEnumerator<int>, IDisposable, IEnumerator
    {
        private int <>1__state;
        private int <>2__current;
        public FakeList <>4__this;

        [DebuggerHidden]
        public <GetEnumerator>d__2(int <>1__state)
        {
            this.<>1__state = <>1__state;
        }

        private bool MoveNext()
        {
            switch (this.<>1__state)
            {
                case 0:
                    this.<>1__state = -1;
                    this.<>2__current = this.<>4__this.one;
                    this.<>1__state = 1;
                    return true;

                case 1:
                    this.<>1__state = -1;
                    this.<>2__current = this.<>4__this.two;
                    this.<>1__state = 2;
                    return true;

                case 2:
                    this.<>1__state = -1;
                    return false;
            }
            return false;
        }

        [DebuggerHidden]
        void IEnumerator.Reset()
        {
            throw new NotSupportedException();
        }

        [DebuggerHidden]
        void IDisposable.Dispose()
        {
        }

        int IEnumerator<int>.Current =>
            this.<>2__current;

        object IEnumerator.Current =>
            this.<>2__current;
    }
}

你看到<GetEnumerator>d__2了吗?类(class)?那是根据你的两个yield return生成的

关于c# - yield 是如何枚举的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37540365/

相关文章:

c# - .NET - 将数据集(XML 数据)流式传输到 ZIP 文件?

c# - 检查 IEnumerable<T> 是否有具有重复属性的项目

c# - 使用表单将新列表项添加到 MVC、Razor、ASP.NET 中的 List<T>

c# - 在 C# 中链接 IEnumerables?

c# - yield 返回和返回

c# - Rhino Mock 执行 yield return

c# - 垃圾收集未按预期运行

c# - 如何将谓词生成器与 linq2sql 和 OR 运算符一起使用

c# - 在发送到服务器之前更改 Webbrowser 发布表单

c# - 检查 yield return 是否包含项目