Demo: https://files.cnblogs.com/files/georgeHeaven/Demo.IEnumerable.rar
一、使用场景
在开发过程中,经常需要使用foreach来循环遍历集合中的元素。虽然.net 类库中已经实现了很多的集合类可以足够我们使用,如List<T>,Array<T>等,但是有的时候我们需要自定义一个自己的集合类如:MyList<T> 也能支持foreach的循环遍历。为了能够实现元素的遍历就必须要实现IEnumerable,对于实现该类接口的类对象来说,不但可以支持foreach的循环遍历,还可以使用C#3.0中的一些扩展方法来访问集合元素。
二、实现
场景:我们有两个类,一个是ClassRoom,一个是student类。我们将要自定义一个集合类StudentCollection,该类实现IEnumerable接口。 我们想要使用foreach来遍历StudentCollection中的每一个学生。
而且我们想要我们的客户端代码调用如下:
1. 实现student类:student类将会作为我们遍历的集合元素。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Demo.IEnumerableInter { public class Student { public string Name { get; set; } public int Age { get; set; } public string School { get; set; } } }
2. 实现ClassRoom类:Classroom类将包含我们自定义的集合,并且通过属性公开给外部访问集合元素。
如下代码中的StudentCollection是我们自定义的集合类(该demo中我们没有涉及泛型的,如果扩展一下我们可以自定义一个泛型集合类如MyCollection<student> students),通过属性Students公开给外部调用。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Demo.IEnumerableInter { public class ClassRoom { private StudentCollection studentList; public StudentCollection Students { get { return studentList; } } public ClassRoom() { Student[] stus = new Student[3] { new Student(){Name ="George Li", Age=24, School="Shenzhen Universty"}, new Student(){Name ="Ruby zhang", Age=24, School="BEIJING Universty"}, new Student(){Name ="Csharp Li", Age=24, School="QINGHUA Universty"} }; studentList = new StudentCollection(stus); } } }
3. IEnumerable 接口实现
首先查看IEnumerable接口如下,为了实现它我们需要实现GetEnumerator()方法。然而该方法返回的却是另一个接口类型IEnumerator(有点叫迭代器),其实不难理解,比如我们自定义类型要实现遍历的接口,你总得告诉你的类你想如何遍历,其实也就是定义一个遍历规则。比如我可以从0开始正序遍历我也可以倒叙遍历,取决于你定义的IEnumerator。
于是我们要先实现一个自己的IEnumerator,查看IEnumerator接口,我们需要实现如下的成员:
现在我们按照接口定义,我们定义一个StudentEnumerator依次实现它的成员:
在实现迭代器以后我们便可以在我们自定义的集合类中实现IEnumerable接口
4. 客户端代码调用
在我们实现了自定义的集合类以后,我们可以在客户端(演示中是控制台输出)通过如下的代码来实现元素的遍历:直接通过我们的自定义集合类,或者通过GetEnumerator使用while来访问(这已经类似于foreach的实现了)
ClassRoom cm1 = new ClassRoom(); //Iterating all students in this class room Console.WriteLine("-----Iterating with Foreach-----"); foreach (Student stu in cm1.Students) { Console.WriteLine("Welcom: ---"+stu.Name); } Console.WriteLine("-----Iterating with GetEnumerator------"); System.Collections.IEnumerator stus = cm1.Students.GetEnumerator(); while (stus.MoveNext()) { Student current = stus.Current as Student; Console.WriteLine("Welcom: ---" + current.Name); } Console.ReadLine();
5. 客户端输出:
【总结】:对于自定义实现IEnumerable接口,最主要在于通过实现IEnumerator接口来设置遍历规则。我们也可以修改上面的例子,通过添加不同的IEnumerator的接口实现,来实现同样的foreach输出不同的结果。这里给了开发人员很大的灵活性。