【发布时间】:2017-08-25 10:09:03
【问题描述】:
很长一段时间以来,我一直试图理解IEnumerable 和IEnumerator 背后的想法。我阅读了所有可以在网上找到的问题和答案,尤其是在 StackOverflow 上,但我并不满意。我明白了应该如何使用这些接口,但不知道为什么要这样使用它们。
我认为我误解的本质是一个操作需要两个接口。我意识到,如果两者都需要,一个可能还不够。所以我采用了foreach 的“硬编码”等效项(正如我发现的here):
while (enumerator.MoveNext())
{
object item = enumerator.Current;
// logic
}
并试图让它与一个界面一起工作,认为会出现问题,这会让我明白为什么需要另一个界面。
于是我创建了一个集合类,并实现了IForeachable:
class Collection : IForeachable
{
private int[] array = { 1, 2, 3, 4, 5 };
private int index = -1;
public int Current => array[index];
public bool MoveNext()
{
if (index < array.Length - 1)
{
index++;
return true;
}
index = -1;
return false;
}
}
并使用foreach 等同于提名集合:
var collection = new Collection();
while (collection.MoveNext())
{
object item = collection.Current;
Console.WriteLine(item);
}
而且它有效!那么这里缺少什么需要另一个接口呢?
谢谢。
编辑: 我的问题与 cmets 中列出的问题不重复:
我的问题是为什么它们的设计方式是这样的,而不是什么它们是什么,它们是如何工作的,以及我们为什么需要首先是他们。
【问题讨论】:
-
那么你怎么能同时从两个不同的线程遍历你的集合呢?
-
想象一下,你想迭代一个文件;您必须打开、迭代和关闭它;将这些操作隐藏在
IEnumerator<T>中似乎是合理的 -
在
while中插入一些条件,然后再次执行另一个循环,你会得到启发。
标签: c# foreach ienumerable ienumerator