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);
}