IEnumrator 枚举器接口
- 这是一个接口,实现这个接口的类,需要实现以下主要功能
- Currnet属性:返回一个obeject对象
- bool MoveNext()方法
- 这是一个接口,实现这个接口的类,需要实现以下主要功能
枚举器的作用是什么?我用enumobj代表这个对象
- 通过得到一个枚举器的对象,我们可以遍历这个对象提供的所有元素
- 遍历这个枚举器的内容时,首先调用enumobj.MoveNext()判断是否成立,成立则说明这个对象可以提供下一个元素,我们就可以通过eunmobj.Currnet来得到这个元素.看下面的Demo
首先定义一个实现该接口的类Students,我们想遍历这个类,得到这个类中记录的所有学生的姓名,当然我们没必要用枚举器来实现,这里只是为了演示
class Students:IEnumerator
{
string[] studentnames = new string[] { "wang", "li", "meng" };
private int index = -1;//当前学生的索引
public object Current
{
get
{
return studentnames[index];
}
}
public bool MoveNext()
{
if (++index > studentnames.Length - 1) return false;
return true;
}
public void Reset()
{
throw new NotImplementedException();
}
}
接下来是入口函数
class Program
{
static void Main(string[] args)
{
IEnumerator enu = new Students();
while (enu.MoveNext())
{
Console.WriteLine(enu.Current);
}
Console.Read();
}
}
输出结果
这里注意一个问题,要把IEnumrator当成一个对象来看待,上述代码中,如果在while循环结束后,再次while循环去遍历这个枚举对象,将不会打印任何姓名,这是因为,该枚举对象结束后,状态已经被保存了,并且没有将index进行重置,所以,再次调用 这个对象的MoveNext()方法,将没有任何反应,如何解决?可以自己想想,我觉的很简单了
IEnumerator和IEnumerable的区别
- IEnumerable接口就定义了一个方法:IEnumerator GetEnumerator()
- 意味着这个接口只是为了获取一个IEnumerator对象
大家都使用过Foreach来遍历一个集合,其实Foreach就是利用了IEnumerable接口来获取该集合上的枚举对象,然后通过不断的MoveNext()来访问每个元素,看下面的代码,两者是等价的
//foreach只能遍历实现了IEnumerable或者带有GetEnumerator()方法的对象,
Students stu = new Students();
foreach (var item in stu)
{
Console.WriteLine(item);
}
//上面的代码只是一种语法糖,编译的时候,对按与下面等价的方式去编译
IEnumerable enumerable = new Students();
IEnumerator enu = enumerable.GetEnumerator();
while (enu.MoveNext())
{
Console.WriteLine(enu.Current);
}
此时应该明白了,IEnumerable 接口,定义的了一种可以返回一个枚举器的一种行为,从而可以利用该枚举进行遍历
下一篇,将理解Yield的用法,从而更好的理解unity协程的实现原理