自定义实现IEnumerable

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输出不同的结果。这里给了开发人员很大的灵活性。

 

posted @ 2017-01-05 21:34  我是小凯哥  阅读(1200)  评论(0编辑  收藏  举报