实现迭代器时,返回IEnumerator和IEnumerable有什么区别?

5

使用 yield return 实现迭代器时,返回 IEnumerator 和返回 IEnumerable 有什么区别吗?


可能是Can anyone explain IEnumerable and IEnumerator to me?的重复问题。 - CodesInChaos
https://dev59.com/Uk3Sa4cB1Zd3GeqPsyve - CodesInChaos
https://dev59.com/71LTa4cB1Zd3GeqPe_ft - CodesInChaos
2
来吧,这不是被引用问题的重复!这个问题关于完全不同的主题:提问者理解IEnumerator和IEnumerable之间的区别,并询问在yield return的特定上下文中如何使用它们。 - Sergey Kalinichenko
3个回答

10

IEnumerableIEnumerator是两个不同的东西。

IEnumerable<T>是可以迭代的序列。

IEnumerator<T>是由IEnumerable<T>返回的对象,用于迭代一次序列。

通常,只有在GetEnumerator()方法中才能返回IEnumerator<T>

yield return对于这两种类型的行为是相同的,唯一的区别在于返回IEnumerable<T>的迭代器方法可以多次执行(每次枚举序列)。
有关此操作方式的更多信息,请参见Jon Skeet的文章


1
恕我直言,这并不是 OP 所询问的内容。他特别询问了 yield return 方法返回其中一个的情况;我甚至不知道从返回 IEnumerator<T> 的函数中使用 yield return 是否可行。 - Sergey Kalinichenko
@dasblinkenlight:yield return 对两者的行为方式都是相同的。据我所知,他只是在问这两种类型之间的区别是什么。 - SLaks
我不同意,因为他明确说“在使用yield return实现迭代器时...”我认为你对于没有区别的评论是对问题更好的回答。 - Sergey Kalinichenko

1
如SLaks所述,枚举器(Enumerator)只能迭代一次,而可枚举对象(IEnumerable)可以生成任意数量的枚举器,允许基础集合被多次迭代。
实际上,主要区别在于有大量方法,例如LINQ和许多与集合交互的方法都处理可枚举对象,而不是枚举器,因此枚举器无法被广泛使用。

你在几个地方说了“Enumerable”,我认为你想说的是“Enumerator”:“...任意数量的枚举器...”,“...所以一个枚举器根本不会...” - Dr. Wily's Apprentice

1

作为迭代器函数的实现者,它对你没有影响。更重要的是迭代器函数的使用者。

一般来说,人们更喜欢拥有一个 IEnumerable<T> 对象,因为你可以在其上进行 foreach 循环,如果你真的需要一个 IEnumerator<T> 对象,那么你可以从 IEnumerable<T> 对象的 GetEnumerator() 方法中获取一个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接