IEnumerable 、 IEnumerator 与 foreach,何时使用什么
我正在浏览 IEnumerable 和 IEnumerator ,但无法清楚地得到一点..如果我们有 foreach,那么为什么我们需要这两个接口? 有没有什么场景我们必须使用接口。如果是,那么有人可以用例子解释一下吗? 欢迎任何建议和意见。 谢谢。
I was going through IEnumerable and IEnumerator , but could not get one point clearly..if we have foreach, then why do we need this two interfaces? Is there any scenario where we have to use interfaces.If yes, then can somebody explain with an example.
Any suggestions and remarks are welcome.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
foreach
在许多情况下使用接口。 如果您想实现一个可供foreach
使用的序列,则需要这些接口。 (尽管迭代器块通常使这个实现任务变得非常简单。)但是,偶尔直接使用迭代器可能会很有用。 一个很好的例子是尝试“配对”两个不同的序列。 例如,假设您收到两个序列 - 一个是姓名,一个是年龄,并且您想将这两个序列一起打印。 您可能会写:
同样,如果您想以不同于其他的方式对待(比如说)第一项,那么使用迭代器可能会很有用:
现在,如果您对
IEnumerator
之间的差异感兴趣> 和IEnumerable
,您可能需要用数据库术语来思考它:将IEnumerable
视为表格,将IEnumerator视为表格。
作为光标。 您可以要求表给您一个新的游标,并且您可以同时在同一个表上有多个游标。可能需要一段时间才能真正理解这种差异,但只要记住列表(或数组,或其他什么)没有任何“你在列表中的位置”的概念,而是在该列表/数组/任何<上的迭代器em>确实有这样的状态是有帮助的。
foreach
uses the interfaces in many cases. You need the interfaces if you want to implement a sequence whichforeach
can then use. (Iterator blocks usually make this implementation task very simple though.)However, just occasionally it can be useful to use the iterators directly. A good example is when trying to "pair up" two different sequences. For example, suppose you receive two sequences - one of names, one of ages, and you want to print the two together. You might write:
Likewise it can be useful to use the iterator if you want to treat (say) the first item differently to the rest:
Now, if you're interested in the difference between
IEnumerator<T>
andIEnumerable<T>
, you might want to think of it in database terms: think ofIEnumerable<T>
as a table, andIEnumerator<T>
as a cursor. You can ask a table to give you a new cursor, and you can have multiple cursors over the same table at the same time.It can take a while to really grok this difference, but just remembering that a list (or array, or whatever) doesn't have any concept of "where you are in the list" but an iterator over that list/array/whatever does have that bit of state is helpful.
乔恩说的话。
IEnumerable
或IEnumerable
:通过实现此对象,它可以为您提供一个迭代器,您可以使用它来遍历序列/集合/集合IEnumerator
或IEnumerator
:如果调用前面接口中定义的 GetEnumerator 方法,您将获得一个迭代器对象作为 IEnumerator 引用。 这使您能够调用 MoveNext() 并获取 Current 对象。foreach
:从某种意义上说,它是一个 C# 构造/外观,因为您不需要知道它在幕后是如何工作的。 它在内部获取迭代器并调用正确的方法,以便您专注于要对每个项目(foreach 块的内容)执行的操作。 大多数时候,您只需要 foreach ,除非您要实现自己的类型或自定义迭代,在这种情况下,您需要了解前两个接口。What Jon said.
IEnumerable
orIEnumerable<T>
: by implementing this an object states that it can give you an iterator that you can use to traverse over the sequence/collection/setIEnumerator
orIEnumerator<T>
: if you call the GetEnumerator method defined in the previous interface, you get an iterator object as an IEnumerator reference. This enables you to call MoveNext() and get the Current object.foreach
: is a C# construct/facade in a sense in that you don't need to know how it works under the hood. It internally gets the iterator and calls the right methods for you to concentrate on what you want to do with each item (the contents of the foreach block). Most of the time, you'd just need foreach unless you're implementing your own type or custom iteration, in which case you'd need to get to know the first 2 interfaces.请记住,您不必必须实现 IEnumerator 及其变体来使用 foreach - IIRC,它所需要的只是一个 GetEnumerator() 方法,该方法返回一个对象,该对象具有一个 MoveNext() 方法,该方法返回bool 和返回对象的 Current 属性。 您不需要使用 IEnumerator 和 IEnumerable,尽管这样做通常是一个非常好的主意。 请参阅此处 了解更多信息。
Bear in mind that you don't have to implement IEnumerator and varients thereof to use foreach - IIRC, all it needs is a GetEnumerator() method that returns an object that has a MoveNext() method returning a bool, and a Current property returning an object. You don't need to use IEnumerator and IEnumerable, although it generally is a very good idea to do so. See here for more information.