foreach可以迭代一些.net本来就为我们做好的类型,比如int,string等等
但是如果想迭代自己的类,就必须自己来写了
首先就要先实现IEnumerator的几个方法,和IEnumerable的GetEnumerator()方法
代码 foreach (person p in persons){ console.writeline(p)}//会解析为IEnumerator enumerator = persons.GetEnumerator(); while (enumerator.MoveNext()){ Person p = (Person)enumerator.Current; Console.WriteLine(p);}
也就是说,foreach循环会调用IEnumerator下的几个方法
他们分别是:public bool MoveNext(),public void Reset(), public object Current属性
顾名思义
代码 public class Person { public Person( string fName, string lName) { this .firstName = fName; this .lastName = lName; } public string firstName; public string lastName; } public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { // _people=pArray????????? _people = new Person[pArray.Length]; for ( int i = 0 ; i < pArray.Length; i ++ ) { _people[i] = pArray[i]; } } /// <summary> /// 接口的实现,返回的是一个PeopleEnum的一个类对象 /// </summary> /// <returns></returns> public IEnumerator GetEnumerator() { return new PeopleEnum(_people); } } public class PeopleEnum : IEnumerator { public Person[] _people; // Enumerators are positioned before the first element // until the first MoveNext() call. int position = - 1 ; public PeopleEnum(Person[] list) { _people = list; } public bool MoveNext() { position ++ ; return (position < _people.Length); } public void Reset() { position = - 1 ; } public object Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } class App { static void Main() { Person[] peopleArray = new Person[ 3 ] { new Person( " John " , " Smith " ), new Person( " Jim " , " Johnson " ), new Person( " Sue " , " Rabon " ), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) { Console.WriteLine(p.firstName + " " + p.lastName); } Console.Read(); } }
总结: 迭代自定义的类,必须实现实现GetEnumerator()方法返回IEnumerator
IEnumerator提供了foreach使用的方法属性
C#2.0有了yield关键字,就不用每次都这样实现IEnumerator接口了 包含yield语句的方法必须返回IEnumerator或者IEnumerable接口 代码 public class person { private string _Name; public string Name { get ; set ; } public person( string name) { Name = name; } public override string ToString() { return this .Name; } } class people { private person[] _person; public people(person[] person) { _person = person; } public IEnumerator GetEnumerator() { for ( int i = 0 ; i < _person.Length; i ++ ) { yield return _person[i]; } } public IEnumerable reverse() { for ( int i = _person.Length - 1 ; i >= 0 ; i -- ) { yield return _person[i]; } } } class Program { static void Main( string [] args) { person[] p = new person[ 3 ] { new person( " John " ), new person( " Jim " ), new person( " Sue " ), }; people pp = new people(p); foreach (person pe in pp) { Console.WriteLine(pe); } foreach (person ppp in pp.reverse()) { Console.WriteLine(ppp); } Console.Read(); } }
我认为yield关键字帮助我们实现了IEnumerator的方法
也可以自己定义迭代的方式,比如以上代码就实现了逆向循环。
参考:C#红皮书
转载于:https://www.cnblogs.com/renjuwht/archive/2009/12/24/1631764.html
