IEnumerator或IEnumerable中的“ Yield”?

时间:2018-09-24 12:11:58

标签: c# iterator yield-return

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

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

我应该在其中使用yield return的正确接口是什么? (当然,收益率的返回值将在Loop中使用,但在哪个接口中使用)。

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

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

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

其他一些使用IEnumerable

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

我假设最好在IEnumerable接口内使用“收益回报”来创建“迭代器”,因为通常IEnumerable负责访问该类(更准确地说,它会返回的一个实例捍卫迭代逻辑的class(Object))。以及在这种情况下编译器究竟发生了什么(yield关键字的糖)。

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

对此有任何想法吗?

1 个答案:

答案 0 :(得分:1)

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

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    if (state == Created && initialThreadId == Environment.CurrentManagedThreadId)
    {
        state = EnumerationStarted;
        return this;
    }
    else
        return new GeneratedEnumerableEnumerator(state: EnumerationStarted);
}
上面代码中的

stateintCreatedEnumerationStarted不是实常数。 state可以具有许多内部值,具体取决于实现的复杂程度。

  

我应该使用良率收益率是什么正确的接口

这取决于您的情况。如果您在自定义集合类型中实现IEnumerable<T>.GetEnumerator(),请使用IEnumerator<T>。而且,如果您需要返回一个IEnumerable<T>且其内容很容易产生,请使用IEnumerable<T>。两者都有道理。