IEnumerable 可以枚举的意思,IEnumerator 迭代器
public interface IEnumerable
{
//返回迭代器,是使用foreach 的前提
[DispId(-4)]
IEnumerator GetEnumerator();
}
public interface IEnumerator
{
//集合中的当前元素。
object Current { get; }
//将枚举数推进到集合的下一个元素。
bool MoveNext();
//将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
void Reset();
}
///自定义IEnumerable
public class AnimalIEnumerable : IEnumerable
{
private string[] arr = new string[] { "dog","cat","fish","pig","tigger","panda","chicken"};
public IEnumerator GetEnumerator()
{
return new AnimalEnumerator(arr);
}
class AnimalEnumerator : IEnumerator
{
private string[] mData;
private int index = -1;
private string mEle;
public AnimalEnumerator(string[] arr)
{
mData = arr;
}
public object Current
{
get { return mEle; }
}
public bool MoveNext()
{
if (index < mData.Length-1)
{
mEle = mData[++index];
return true;
}
return false;
}
public void Reset()
{
index = -1;
}
}
}
///方法一
AnimalIEnumerable animals = new AnimalIEnumerable();
foreach (string item in animals)
{
Console.WriteLine(item);
}
///方法二
var enumerator = animals.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
方法一调用和方法二调用 等价
总结:
1. getEnumerator() 返回迭代器
2. Current 返回当前迭代的值
3. MoveNext() 判断是否可以迭代,并让current 指向下一个值。
4. reset() 重置枚举器的状态
也就是说foreach其实是一种语法糖,用来简化对可枚举元素的遍历代码。而被遍历的类通过实现IEnumerable接口和一个相关的IEnumerator枚举器来实现遍历功能。