这个问题已经在这里有一个答案:
- 谁能解释IEnumerable和IEnumerator的给我吗? 16个回答
我所经历的IEnumerable和IEnumerator的,但不能得一分clearly..if我们的foreach,那么为什么我们需要这两个接口? 是否有一个地方,我们必须使用interfaces.If肯定的,那么有人可以用一个例子来说明任何情况。 任何建议和意见是值得欢迎的。 谢谢。
这个问题已经在这里有一个答案:
我所经历的IEnumerable和IEnumerator的,但不能得一分clearly..if我们的foreach,那么为什么我们需要这两个接口? 是否有一个地方,我们必须使用interfaces.If肯定的,那么有人可以用一个例子来说明任何情况。 任何建议和意见是值得欢迎的。 谢谢。
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>
的光标。 你可以要求一个表给你一个新的光标,你可以在同一时间有超过同桌多个游标。
这可能需要一段时间才能真正神交这种差异,而只是记住一个列表(或阵列,或其他)没有“你在哪里列表”中的任何概念,但在该列表/数组一个迭代器/不管用什么方法有状态的该位是很有帮助的。
什么乔恩说。
IEnumerable
或IEnumerable<T>
通过实现此目的指出,它可以给你,你可以使用遍历在序列/收集/集的迭代 IEnumerator
或IEnumerator<T>
如果调用在前面的接口中定义的GetEnumerator方法,将得到的迭代器对象作为一个IEnumerator参考。 这使您能够调用的MoveNext()和获取当前对象。 foreach
:是的,你不需要知道它是如何工作的引擎盖下一个意义上的C#构造/门面。 它在内部得到的迭代器和调用正确的方法让你专注于你想要的每个项目(在foreach块的内容)做什么。 大多数时候,你只需要的foreach除非你实现你自己的类型或自定义的迭代,在这种情况下,你需要去了解前2个接口。 记住,你实现IEnumerator及其一些变体使用的foreach - IIRC,它需要一切是返回具有的MoveNext()方法返回一个布尔对象的的GetEnumerator()方法,以及当前的财产返还一个东西。 你不需要使用的IEnumerator和IEnumerable,尽管它通常是一个非常好的主意,这样做。 请参阅这里了解更多信息。