IEnumerable / IEnumerator
首先,IEnumerable / IEnumerator 接口定义如下:
public interface IEnumerable /// 可枚举接口
{
IEnumerator GetEnumerator();
}
public interface IEnumerator /// 枚举器接口
{
object Current { get; }
bool MoveNext();
void Reset();
}
注:Current 没有 set 方法,在 foreach 中不能修改元素 var item 的值。
· IEnumerable:声明式的接口,声明实现了该接口的类是可枚举类型;
· IEnumerator:实现式的接口,IEnumerator 对象说明如何实现一个枚举器;
通过继承 IEnumerable / IEnumerator 接口实现自定义类使用 foreach 语句来遍历自身元素。逻辑关系图:
People <-> MyClass 实现 IEnumerable 接口的 GetEnumerator()方法
EnumeratorPeople <-> MyEnumerator 实现 IEnumerator 接口
· 定义Person类
public class Person
{
private string name;
private int age;
public Person(string _name, int _age){
this.name = _name, this.age = _age;
}
public override string ToString(){
return string.Format("Name:{0},Age:{1}.", name, age);
}
}
数组定义见主函数,以下2种遍历数组的方法等同,因为所有数组的基类都是 System.Array ,System.Array 类实现了 IEnumerable 接口,可以直接通过 GetEnumerator() 方法返回枚举数对象,枚举数对象可以依次返回请求的数组的元素。
// 利用 foreach 遍历数组
foreach (var person in persons)
Console.WriteLine(person.ToString());
// 利用 IEnumerable ~ IEnumerator 遍历数组
IEnumerator it = persons.GetEnumerator();
while (it.MoveNext()){
Person obj = (Person)(it.Current); // 需强制类型转换
Console.WriteLine(obj.ToString());
}
· 定义People类 (MyClass)
public class People
{
private Person[] persons;
public People(Person[] _persons){
persons = new Person[_persons.Length];
for (int i = 0; i < _persons.Length; ++i){
persons[i] = _persons[i];
}
}
}
注意,People 类的 persons 数组是 private 变量,在主测函数中是无法遍历访问的。
方法 1:将 private 更改为 public:
foreach (var person in people.persons)
Console.WriteLine(person.ToString());
方法 2:People 类继承 IEnumerable 接口并实现 GetEnumerator() 方法,有 2 种方法:
[-1-]. 利用数组默认实现了 IEnumerable 和 IEnumerator 接口的事实,重新定义 People 类:
public class People : IEnumerable
{
... ...
publ