我正在浏览IEnumerable和IEnumerator,但无法清楚地得到一点。如果我们有foreach,那么为什么我们需要这两个接口?有没有我们必须使用接口的场景。如果是,那么有人可以用一个例子来解释。 欢迎任何建议和评论。 谢谢。IEnumerable,IEnumerator与foreach,何时使用什么
22
A
回答
46
foreach
使用接口在许多情况下。如果你想实现那么你需要这些接口,然后foreach
可以使用。 (虽然迭代器块通常使这个实现任务非常简单)。
但是,只是偶尔直接使用迭代器会很有用。一个很好的例子是当试图“配对”两个不同的序列时。例如,假设您收到两个序列 - 名称之一,年龄之一,并且您想将它们打印在一起。你可能会这样写:
static void PrintNamesAndAges(IEnumerable<string> names, IEnumerable<int> ages)
{
using (IEnumerator<int> ageIterator = ages.GetEnumerator())
{
foreach (string name in names)
{
if (!ageIterator.MoveNext())
{
throw new ArgumentException("Not enough ages");
}
Console.WriteLine("{0} is {1} years old", name, ageIterator.Current);
}
if (ageIterator.MoveNext())
{
throw new ArgumentException("Not enough names");
}
}
}
同样也可以是,如果你想治疗(说)不同的使用迭代器的第一个项目到受用:
public T Max<T>(IEnumerable<T> items)
{
Comparer<T> comparer = Comparer<T>.Default;
using (IEnumerator<T> iterator = items.GetEnumerator())
{
if (!iterator.MoveNext())
{
throw new InvalidOperationException("No elements");
}
T currentMax = iterator.Current;
// Now we've got an initial value, loop over the rest
while (iterator.MoveNext())
{
T candidate = iterator.Current;
if (comparer.Compare(candidate, currentMax) > 0)
{
currentMax = candidate;
}
}
return currentMax;
}
}
现在,如果你对IEnumerator<T>
和IEnumerable<T>
之间的区别感兴趣,您可能想要用数据库术语思考它:将IEnumerable<T>
作为表,将IEnumerator<T>
作为游标。您可以请求一个表给您一个新的游标,并且您可以同时在同一个表上有多个游标。
可能需要一段时间才能真正理解这种差异,但只要记住一个列表(或数组,或其他)没有任何“你在列表中的位置”的概念,而是在列表/ array/whatever does有那么点的状态是有帮助的。
8
乔恩说什么。
IEnumerable
或IEnumerable<T>
:通过实施此对象指出,它可以给你,你可以用它来遍历在序列/集合的迭代器/集IEnumerator
或IEnumerator<T>
:如果你调用定义GetEnumerator方法在前一个界面中,您将获得一个迭代器对象作为IEnumerator引用。这使您可以调用MoveNext()并获取当前对象。foreach
:从某种意义上说,它是C#构造/外观,因为您不需要知道它如何在引擎盖下工作。它在内部获取迭代器并为您调用正确的方法专注于您想要对每个项目执行的操作(foreach块的内容)。大多数情况下,除非实现自己的类型或自定义迭代,否则只需要foreach,在这种情况下,您需要了解前2个接口。
6
记住,你不有来实现IEnumerator及其一些变体使用的foreach - IIRC,它需要一切是返回具有的MoveNext()方法返回一个对象的GetEnumerator()方法一个bool和一个Current属性返回一个对象。您不需要使用IEnumerator和IEnumerable,但通常这是一个非常好的主意。有关更多信息,请参阅here。
相关问题
- 1. IEnumerable和IEnumerator的或foreach C#
- 2. IEnumerable&IEnumerator
- 3. foreach是否为内置类型使用IEnumerator/IEnumerable?
- 4. IEnumerable&IEnumerator后缀
- 5. 是Yield Return == IEnumerable&IEnumerator?
- 6. C++/CLI IEnumerable和IEnumerator实现
- 7. 的IEnumerator IEnumerable的VB到C#
- 8. 什么演员IEnumerable <T> IEnumerator <T>做
- 9. 什么时候应该在IE中使用IEnumerator进行循环?
- 10. 当使用“yield”时,为什么编译器生成的类型实现IEnumerable和IEnumerator
- 11. IEnumerator的目的是什么
- 12. 寻找IEnumerable/IEnumerator更快的实现
- 13. 何时使用IEnumerable over IEnumerable <>
- 14. 为什么在IEnumerable上使用IList?
- 15. 为什么使用IQueryable代替IEnumerable与MEF目录?
- 16. 什么时候使用折叠和何时在Scala中使用foreach
- 17. IEnumerable的<XElement>和foreach
- 18. foreach按字符串的IEnumerable引用
- 19. 如何在一个IEnumerable对象中执行foreach foreach
- 20. 的IEnumerable <T>和IEnumerator的 - 一些说明,请
- 21. 调用图IEnumerator
- 22. 什么时候使用StringBuilder.AppendLine/string.Format与StringBuilder.AppendFormat?
- 23. 什么时候会使用ObjectInputStream.readUshared()与.readObject()?
- 24. Flex - Remoting与HTTPService - 什么时候使用?
- 25. 什么时候使用View()与RedirectToAction
- 26. 简单IEnumerator使用(使用示例)
- 27. 返回IEnumerable <T>和IEnumerator <T>的迭代器方法有什么区别吗?
- 28. 当在IEnumerable上调用ToArray()时会发生什么?
- 29. foreach与类的使用php
- 30. 使用forEach与Get-ChildItem -recurse
感谢乔恩为你提供的所有帮助。我现在明白了,并且将会学习更多,以便说清楚。 另外我发现下面的链接非常有用: http://stackoverflow.com/questions/558304/can-anyone-explain-ienumerable-and-ienumerator-to-me – Wondering 2009-07-06 07:12:43
这是一个例子,你坚持使用IEnumerator只是保持高效。 http://stackoverflow.com/questions/1018407/what-is-the-most-elegant-way-to-get-a-set-of-items-by-index-from-a-collection/1025137#1025137 – 2009-07-06 11:59:04
@Jon Skeet我真的很喜欢你编码方式Max的方法。我有一个问题。你使用IEnumberator构造。我知道使用处理它里面的东西()。你为什么在IEnumberator上使用它? –
2012-05-29 05:47:38