C#如何实现自定义集合的IEnumerable 和 IEnumerator 接口并使用foreach访问自定义集合
抛砖引玉:
static void Main(string[] args) { int[] array = new int[] { 5,4,3,2,1}; foreach (int i in array) Console.WriteLine("Number:"+i); Console.ReadKey(); } /** * -------------执行结果------------- * Number:5 * Number:4 * Number:3 * Number:2 * Number:1 * -------------执行结果------------- */
问题:为什么使用foreach可以遍历出数组中的所有元素呢?
原因:数组是可枚举类型,它可以按需提供枚举数,枚举数可以依次返回请求的数组的元素。而foreach结构被设计用来和可枚举类型一起使用,只要给foreach的遍历对象是可枚举类型,则她就会执行如下行为:
- 通过调用GetEnumerator方法获取对象(如:数组)的枚举数(即数组中的元素值)
- 从枚举数中请求每一项并把她作为迭代遍历
因为数组是可枚举类型,所以我就使用使用IEnumerator接口来实现枚举数以模仿foreach的循环遍历
实现代码如下:
static void Main(string[] args) { int[] array = new int[] { 5,4,3,2,1}; IEnumerator ie = array.GetEnumerator();//获取枚举数 while (ie.MoveNext())//移动下一项 { //最初,枚举数定位在集合中第一个元素前,在此位置上,Current 属性未定义 //因此,在读取 Current 的值之前,必须调用 MoveNext 方法将枚举数提前到集合的第一个元素 int i = (int)ie.Current;//获取当前项 Console.WriteLine("Number:" + i); } } /** * -------------执行结果------------- * Number:5 * Number:4 * Number:3 * Number:2 * Number:1 * -------------执行结果------------- */
实现IEnumerable 和 IEnumerator 接口
以下示例演示如何实现自定义集合的IEnumerable 和 IEnumerator 接口,在此示例中,没有显式调用这些接口的成员,但实现了它们,以便支持使用 foreach循环访问该集合
要点:
- 显示实现IEnumerable接口的GetEnumerator成员函数
- 显示实现IEnumerator接口的Current,Reset(),MoveNext()
示意图:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { // 实现IEnumerator接口 public class PersonIEnumerator : IEnumerator { string[] Person; int position = -1; public PersonIEnumerator(string[] thePersons) { Person = new string[thePersons.Length]; for (int i = 0; i < thePersons.Length; i++) { Person[i] = thePersons[i]; } } //IEnumerator接口的特性1 public object Current { get { return Person[position]; } } //IEnumerator接口的特性2 public bool MoveNext() { if (position < Person.Length - 1) { position++; return true; } else return false; } //IEnumerator接口的特性3 public void Reset() { position = -1; } } //实现IEnumerable接口 public class MyPersons : IEnumerable { string[] strArr = new string[] { "周星驰", "莫言", "贝克汉姆", "林志颖" }; //返回IEnumerator类型的对象 public IEnumerator GetEnumerator() { return new PersonIEnumerator(strArr); } } class Program { static void Main(string[] args) { MyPersons mp = new MyPersons(); foreach (string name in mp) { Console.WriteLine("{0}", name); } Console.ReadKey(); } } /** * -------------执行结果------------- * 周星驰 * 莫言 * 贝克汉姆 * 林志颖 * -------------执行结果------------- */ }
注:C# 语言的 foreach 语句隐藏了枚举数的复杂性。因此,建议使用 foreach,而不直接操作枚举数
原创文章,转载请注明出处:http://www.cnblogs.com/hongfei