有人能给我解释一下IEnumerable和IEnumerator吗?
例如,什么时候用它胜过foreach?IEnumerable和IEnumerator的区别是什么?为什么我们需要使用它?
有人能给我解释一下IEnumerable和IEnumerator吗?
例如,什么时候用它胜过foreach?IEnumerable和IEnumerator的区别是什么?为什么我们需要使用它?
当前回答
通过类比+代码演练进行解释
类比:假设你是一架飞机上的侦探。你得在所有乘客中找到嫌疑人。
一架飞机只能这样做,如果它是:
可数名词, 如果它有计数器。
可数是什么意思?
如果一家航空公司是可数的,这意味着飞机上必须有一名空乘人员,他的唯一工作就是数数:
柜台/空乘人员必须先于第一位乘客开始工作。(即空乘人员)必须“下一个移动”到过道的第一个座位。 然后他/她要记录:(i)坐在座位上的人,以及(ii)他们目前在过道上的位置。
计数器一直往前走,直到他到达飞机的尽头。
让我们把它和IEnumerables联系起来
foreach (Passenger passenger in Plane)
// the airline hostess is now at the front of the plane
// and slowly making her way towards the back
// when she get to a particular passenger she gets some information
// about the passenger and then immediately heads to the cabin
// to let the captain decide what to do with it
{ // <---------- Note the curly bracket that is here.
// we are now cockpit of the plane with the captain.
// the captain wants to give the passenger free
// champaign if they support manchester city
if (passenger.supports_mancestercity())
{
passenger.getFreeChampaign();
}
else
{
// you get nothing! GOOD DAY SIR!
}
} // <---- Note the curly bracket that is here!
// the hostess has delivered the information
// to the captain and goes to the next person
// on the plane (if she has not reached the
// end of the plane)
总结
换句话说,有计数器的东西是可数的。计数器必须(基本上):(i)记住它的位置(状态),(ii)能够下一步移动,(iii)了解他正在处理的当前对象。
可枚举的只是“可数的”的一个花哨的词。
其他回答
通过类比+代码演练进行解释
类比:假设你是一架飞机上的侦探。你得在所有乘客中找到嫌疑人。
一架飞机只能这样做,如果它是:
可数名词, 如果它有计数器。
可数是什么意思?
如果一家航空公司是可数的,这意味着飞机上必须有一名空乘人员,他的唯一工作就是数数:
柜台/空乘人员必须先于第一位乘客开始工作。(即空乘人员)必须“下一个移动”到过道的第一个座位。 然后他/她要记录:(i)坐在座位上的人,以及(ii)他们目前在过道上的位置。
计数器一直往前走,直到他到达飞机的尽头。
让我们把它和IEnumerables联系起来
foreach (Passenger passenger in Plane)
// the airline hostess is now at the front of the plane
// and slowly making her way towards the back
// when she get to a particular passenger she gets some information
// about the passenger and then immediately heads to the cabin
// to let the captain decide what to do with it
{ // <---------- Note the curly bracket that is here.
// we are now cockpit of the plane with the captain.
// the captain wants to give the passenger free
// champaign if they support manchester city
if (passenger.supports_mancestercity())
{
passenger.getFreeChampaign();
}
else
{
// you get nothing! GOOD DAY SIR!
}
} // <---- Note the curly bracket that is here!
// the hostess has delivered the information
// to the captain and goes to the next person
// on the plane (if she has not reached the
// end of the plane)
总结
换句话说,有计数器的东西是可数的。计数器必须(基本上):(i)记住它的位置(状态),(ii)能够下一步移动,(iii)了解他正在处理的当前对象。
可枚举的只是“可数的”的一个花哨的词。
实现IEnumerable可以让你获得一个列表的IEnumerator。
IEnumerator允许使用yield关键字以foreach样式顺序访问列表中的项。
在foreach实现之前(例如在Java 1.4中),迭代列表的方法是从列表中获取一个枚举器,然后向它请求列表中的“下一个”项,只要作为下一个项返回的值不为空。Foreach只是隐式地将其作为一种语言特性来实现,与lock()在幕后实现Monitor类的方式相同。
我期望foreach工作在列表上,因为它们实现了IEnumerable。
实现IEnumerable意味着你的类返回一个IEnumerator对象:
public class People : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator()
{
// return a PeopleEnumerator
}
}
实现IEnumerator意味着你的类返回迭代的方法和属性:
public class PeopleEnumerator : IEnumerator
{
public void Reset()...
public bool MoveNext()...
public object Current...
}
这就是区别所在。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Enudemo
{
class Person
{
string name = "";
int roll;
public Person(string name, int roll)
{
this.name = name;
this.roll = roll;
}
public override string ToString()
{
return string.Format("Name : " + name + "\t Roll : " + roll);
}
}
class Demo : IEnumerable
{
ArrayList list1 = new ArrayList();
public Demo()
{
list1.Add(new Person("Shahriar", 332));
list1.Add(new Person("Sujon", 333));
list1.Add(new Person("Sumona", 334));
list1.Add(new Person("Shakil", 335));
list1.Add(new Person("Shruti", 336));
}
IEnumerator IEnumerable.GetEnumerator()
{
return list1.GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
Demo d = new Demo(); // Notice here. it is simple object but for
//IEnumerator you can get the collection data
foreach (Person X in d)
{
Console.WriteLine(X);
}
Console.ReadKey();
}
}
}
/*
Output :
Name : Shahriar Roll : 332
Name : Sujon Roll : 333
Name : Sumona Roll : 334
Name : Shakil Roll : 335
Name : Shruti Roll : 336
*/
实现IEnumerable的对象允许其他人访问它的每一项(通过枚举器)。 实现IEnumerator的对象是在进行迭代。它循环遍历一个可枚举对象。
可以把可枚举对象想象成列表、堆栈、树。