using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Collections; using System.Data.Common; using System.Data; using System.Security.Util; using System.Text.RegularExpressions; namespace Demo { class Program { static void Main(string[] args) { Person[] ps = { new Person("a", 1), new Person("b", 2), new Person("c", 3) }; People p = new People(ps); foreach (Person item in p) { Console.WriteLine("name={0},age={1}",item.Name,item.Age); } Console.Read(); } } class Person { public string Name; public int Age; public Person(string name, int age) { Name = name; Age = age; } } class PersonEnum : IEnumerator { Person []ps; public PersonEnum(Person[]ps) { this.ps=ps; } int position = -1; public void Reset (){ position=-1;} public bool MoveNext() { ++position; return position < ps.Length; } public object Current { get { return ps[position];} } } class People:IEnumerable { Person[] ps; public People(Person[]ps) { this.ps = ps; } public IEnumerator GetEnumerator() { return new PersonEnum(ps); } } }
上边例子中,如果将Main中的代码换成下边这样子也能实现foreach啊,为什么要像上面这样写呢?
Person[] ps = { new Person("a", 1), new Person("b", 2), new Person("c", 3) }; foreach (Person item in ps) { Console.WriteLine("name={0},age={1}",item.Name,item.Age); } Console.Read();
foreach循环的数据集合必须实现IEnumerable,这个接口就一个方法 GetEnumerator,返回接口IEnumerator类型的对象。
凡是要让IEnumerable接口的方法GetEnumerator返回的对象都必须实现接口IEnumerator。
这两个接口可以实现在统一个对象上,也可以是在不同的对象上。
当实现在同一个对象上的时候,GetEnumerator则可以简单的返回this(当然,具体情况还是要具体分析)。
基本上,很多集合对象都同时实现了这两个接口。
数组也继承了这两个接口,所以可以直接foreach。
实现接口的时候可以用yield return.
如果不实现接口就可以用yield return
只要返回值是IEnumerable就可以了。
用到数组或者集合的时候都要实现
本质就是对设计模式中迭代器模式的一个实现,建议看下这个模式就知道背后的原理了