首先要明白两个类型:可枚举类和枚举器类
可枚举类是指一个类中包含了GetEumerator(),这样的类就称之为可枚举类。
GetEumerator()的返回值是一个接口:IEumerator。
而定义IEumerator接口的类即称为枚举器类。
这个接口包含1个属性Current和2个方法MoveNext()、Reset(),用这三个成员就可以实现对可枚举类对象中的一组数据的遍历(枚举)。
GetEumerator()返回枚举器类的对象,对象自动转换成为IEumerator接口。
internal class Program
{
static void Main(string[] args)
{
A aaa=new A();
foreach(var x in aaa)
{
Console.WriteLine(x);
}
}
}
class A
{
int[] a = { 1, 2, 3 };
public IEnumerator GetEnumerator()
{
return new ColorEumerator(a);
}
}
class ColorEumerator : IEnumerator
{
int[] a;
public ColorEumerator(int[] b)
{
a = b;
}
int position = -1;
public object Current
{
get { return a[position]; }
}
public bool MoveNext()
{
if (position < a.Length - 1)
{
position++;
return true;
}
else
return false;
}
public void Reset()
{
position = -1;
}
}
(IEnumerator泛型和IEnumerator并无大的不同,仅仅是需要多定义1个IDisposable.Dispose(),以及把Current属性进行转换,从返回object类型到T类型。)
class A
{
int[] a = { 1, 2, 3 };
public IEnumerator<int> GetEnumerator()
{
return new ColorEumerator(a);
}
}
class ColorEumerator : IEnumerator<int>
{
int[] a;
public ColorEumerator(int[] b)
{
a = b;
}
int position = -1;
public int Current
{
get { return a[position]; }
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
if (position < a.Length - 1)
{
position++;
return true;
}
else
return false;
}
public void Reset()
{
position = -1;
}
void IDisposable.Dispose(){}
}
}
采用迭代器后,GetEnumerator()的内容可以这样写,只要能用yield返回一个数据集合就可以:
class A
{
public IEnumerator GetEnumerator()
{
for (int i = 1; i < 4; i++)
{
yield return i;
}
}
}
IEumerable是一个接口,它仅包含GetEumerator() ,迭代器也可以返回IEumerable接口。但由于返回的是接口,而不是GetEumerator()本身,为了让A类成为可枚举的,需要进行一下转化:
class A
{
public IEnumerator GetEnumerator()
{
return GetSomeInts().GetEnumerator();
}
public IEnumerable GetSomeInts()
{
for (int i = 1; i < 4; i++)
{
yield return i;
}
}
}
枚举器还可以作为属性来使用:
class A
{
public IEnumerator GetEnumerator()
{
return GetSomeInts;
}
public IEnumerator GetSomeInts
{
get
{
for (int i = 1; i < 4; i++)
{
yield return i;
}
}
}
}