C# ';收益率';在IEnumerator或IEnumerable中?

C# ';收益率';在IEnumerator或IEnumerable中?,c#,iterator,yield-return,C#,Iterator,Yield Return,我一直在寻找这一点,但我还没有得到任何信息 我看了很多关于“收益率回报”的视频和红色文章,我想我对它有了更好的理解,但有一点我不能理解 什么是正确的接口,我应该使用收益率返回到它?(当然,收益率将在循环中使用,但在哪个接口中使用) 我的意思是在这一点上有变化,我看到一些人在IEnumerator中创建了一个“迭代器”,例如: static string[] Names = { "Name1", "Name2", "Name3" }; static IEnumerator Test()

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

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

什么是正确的接口,我应该使用收益率返回到它?(当然,收益率将在循环中使用,但在哪个接口中使用)

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

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

    static IEnumerator Test()
    {
        for (int i = 0; i < Names.Length; i++)
        {
            yield return Names[i];
        }
    }
我假设最好在
IEnumerable
接口中使用“Yield return”创建一个“迭代器”,因为通常IEnumerable负责访问类(更准确地说,它返回类(对象)的实例),以保护迭代逻辑。在这种情况下,编译器(sugarofyield关键字)会发生什么

 private static IEnumerable Test() => new <Test>d__1(-2);
//decompiled code of Test() method above Using reflector tool
private static IEnumerable Test()=>newd__1(-2);
//使用reflector工具反编译上述Test()方法的代码

有什么想法吗

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

IEnumerator IEnumerable.GetEnumerator()
{
if(state==Created&&initialThreadId==Environment.CurrentManagedThreadId)
{
状态=枚举开始;
归还这个;
}
其他的
返回新的GeneratedEnumerableEnumerator(状态:EnumerationStarted);
}
上面代码中的
状态
是一个
int
创建的
枚举开始的
不是真正的常量名称<根据实现的复杂性,代码>状态可以有许多内部值

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


这取决于你的情况。如果在自定义集合类型中实现了
IEnumerable.GetEnumerator()
,请使用
IEnumerator
。如果您需要返回一个
IEnumerable
,它的内容可以很容易地生成,那么使用
IEnumerable
。两者都有意义。

返回
IEnumerable
,而不是
IEnumerator
。所有linq扩展方法都使用
IEnumerable
。当需要非标准的枚举方法时,只需定义
IEnumerator
。您的
Test
方法应该返回一个
IEnumerable
,该值可以使用
foreach
循环进行枚举。
 private static IEnumerable Test() => new <Test>d__1(-2);
//decompiled code of Test() method above Using reflector tool
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    if (state == Created && initialThreadId == Environment.CurrentManagedThreadId)
    {
        state = EnumerationStarted;
        return this;
    }
    else
        return new GeneratedEnumerableEnumerator(state: EnumerationStarted);
}