zoukankan      html  css  js  c++  java
  • 自定义实现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输出不同的结果。这里给了开发人员很大的灵活性。

  • 相关阅读:
    问题建模---大纲---待补充
    塞库报表封装问题分析--一篇不太成功的问题分析报告
    哲学的根本问题--以人为本
    什么是本体论
    知行合一是做人的最高境界
    什么是问题?--人类才是最大的问题--所有的问题都是在人类认识世界和改造世界中产生的
    还原论与what、how、why
    selinux 开启和关闭
    Macbook上打开多个终端的方法
    PHPStorm 快捷键大全(Win/Linux/Mac)
  • 原文地址:https://www.cnblogs.com/georgeHeaven/p/6254129.html
Copyright © 2011-2022 走看看