IEnumerator 或 IEnumerable 中的“产量”?

Amm*_*hdi 7 c# iterator yield-return

我一直在寻找这一点,但我还没有得到任何有关它的信息!

我看了很多关于“收益回报”的视频和红色文章,我想我对此有了更好的理解,但有一点我无法理解

我应该使用yield return 的正确接口是什么?(当然Yield返回会在Loop中使用但在哪个接口中)。

我的意思是这一点有所不同,我看到有些人在 中创建了一个“迭代器”IEnumerator,例如:

static string[] Names = { "Name1", "Name2", "Name3" };

    static IEnumerator Test()
    {
        for (int i = 0; i < Names.Length; i++)
        {
            yield return Names[i];
        }
    }
Run Code Online (Sandbox Code Playgroud)

和其他一些人使用IEnumerable

        static IEnumerable Test()
    {
        for (int i = 0; i < Names.Length; i++)
        {
            yield return Names[i];
        }
    }
Run Code Online (Sandbox Code Playgroud)

我假设最好在IEnumerable接口中使用“Yield return”创建一个“迭代器”,因为一般来说 IEnumerable 负责访问该类(更准确地说,它返回一个类(对象)的实例)迭代的逻辑。在这种情况下,编译器到底发生了什么(yield 关键字的糖)。

 private static IEnumerable Test() => new <Test>d__1(-2);
//decompiled code of Test() method above Using reflector tool
Run Code Online (Sandbox Code Playgroud)

对此有什么想法吗?

Gyö*_*zeg 4

编译器支持这两种接口,实际上,如果返回值为IEnumerable<T>,生成的类将实现这两​​个接口,GetEnumerator()其实现如下(大致):

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    if (state == Created && initialThreadId == Environment.CurrentManagedThreadId)
    {
        state = EnumerationStarted;
        return this;
    }
    else
        return new GeneratedEnumerableEnumerator(state: EnumerationStarted);
}
Run Code Online (Sandbox Code Playgroud)

state上面的代码中的int,CreatedEnumerationStarted不是真正的常量名称。state根据实现的复杂性,可以有许多内部值。

我应该使用yield return 的正确接口是什么

这取决于你的情况。IEnumerable<T>.GetEnumerator()如果您在自定义集合类型中实现,请使用IEnumerator<T>. 如果您需要返回一个IEnumerable<T>可以轻松生成其内容的 ,那么请使用IEnumerable<T>. 两者都有道理。