有人能给我解释一下IEnumerable和IEnumerator吗?
例如,什么时候用它胜过foreach?IEnumerable和IEnumerator的区别是什么?为什么我们需要使用它?
有人能给我解释一下IEnumerable和IEnumerator吗?
例如,什么时候用它胜过foreach?IEnumerable和IEnumerator的区别是什么?为什么我们需要使用它?
当前回答
实现IEnumerable本质上意味着可以遍历对象。这并不一定意味着它是一个数组,因为有一些列表不能被索引,但你可以枚举它们。
IEnumerator是用于执行迭代的实际对象。它控制从一个对象移动到列表中的下一个对象。
大多数情况下,IEnumerable和IEnumerator被透明地用作foreach循环的一部分。
其他回答
例如,什么时候用它胜过foreach?
你不用IEnumerable "over" foreach。实现IEnumerable使得使用foreach成为可能。
当你写这样的代码时:
foreach (Foo bar in baz)
{
...
}
它在功能上相当于这样写:
IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
bar = (Foo)bat.Current
...
}
所谓“功能等效”,我指的是编译器实际将代码转换成的内容。在本例中,除非baz实现了IEnumerable,否则不能在baz上使用foreach。
IEnumerable表示baz实现了该方法
IEnumerator GetEnumerator()
该方法返回的IEnumerator对象必须实现这些方法
bool MoveNext()
and
Object Current()
第一个方法前进到创建枚举器的IEnumerable对象中的下一个对象,如果完成则返回false,第二个方法返回当前对象。
. net中任何你可以迭代的东西都实现了IEnumerable。如果您正在构建自己的类,并且它还没有从实现了IEnumerable的类继承,那么您可以通过实现IEnumerable(并通过创建其新的GetEnumerator方法将返回的枚举器类)使您的类在foreach语句中可用。
实现IEnumerable本质上意味着可以遍历对象。这并不一定意味着它是一个数组,因为有一些列表不能被索引,但你可以枚举它们。
IEnumerator是用于执行迭代的实际对象。它控制从一个对象移动到列表中的下一个对象。
大多数情况下,IEnumerable和IEnumerator被透明地用作foreach循环的一部分。
小贡献。
正如他们中的许多人解释“何时使用”和“与foreach一起使用”。 我想在这里添加另一个状态差异,以询问IEnumerable和IEnumerator之间的差异。
我根据下面的讨论线程创建了下面的代码示例。
IEnumerable, IEnumerator vs foreach,什么时候使用什么 IEnumerator和IEnumerable的区别是什么?
Enumerator保留函数调用之间的状态(迭代位置),而Enumerable则不保留迭代。
下面是带有注释的测试示例。
专家请补充/纠正我。
static void EnumerableVsEnumeratorStateTest()
{
IList<int> numList = new List<int>();
numList.Add(1);
numList.Add(2);
numList.Add(3);
numList.Add(4);
numList.Add(5);
numList.Add(6);
Console.WriteLine("Using Enumerator - Remembers the state");
IterateFrom1to3(numList.GetEnumerator());
Console.WriteLine("Using Enumerable - Does not Remembers the state");
IterateFrom1to3Eb(numList);
Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}
static void IterateFrom1to3(IEnumerator<int> numColl)
{
while (numColl.MoveNext())
{
Console.WriteLine(numColl.Current.ToString());
if (numColl.Current > 3)
{
// This method called 3 times for 3 items (4,5,6) in the collection.
// It remembers the state and displays the continued values.
IterateFrom3to6(numColl);
}
}
}
static void IterateFrom3to6(IEnumerator<int> numColl)
{
while (numColl.MoveNext())
{
Console.WriteLine(numColl.Current.ToString());
}
}
static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
foreach (int num in numColl)
{
Console.WriteLine(num.ToString());
if (num>= 5)
{
// The below method invokes for the last 2 items.
//Since it doesnot persists the state it will displays entire collection 2 times.
IterateFrom3to6Eb(numColl);
}
}
}
static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
Console.WriteLine();
foreach (int num in numColl)
{
Console.WriteLine(num.ToString());
}
}
实现IEnumerable可以让你获得一个列表的IEnumerator。
IEnumerator允许使用yield关键字以foreach样式顺序访问列表中的项。
在foreach实现之前(例如在Java 1.4中),迭代列表的方法是从列表中获取一个枚举器,然后向它请求列表中的“下一个”项,只要作为下一个项返回的值不为空。Foreach只是隐式地将其作为一种语言特性来实现,与lock()在幕后实现Monitor类的方式相同。
我期望foreach工作在列表上,因为它们实现了IEnumerable。
IEnumerable实现了GetEnumerator。当调用时,该方法将返回一个IEnumerator,它实现了MoveNext, Reset和Current。
因此,当你的类实现IEnumerable时,你是在说你可以调用一个方法(GetEnumerator)并返回一个新的对象(一个IEnumerator),你可以在循环中使用,比如foreach。