迭代器的实现

来源:互联网 发布:淘宝图片护盾从哪进? 编辑:程序博客网 时间:2024/06/06 01:34

http://2sws.blog.163.com/blog/static/179102492009843454870/

 

迭带器---枚举对象并非必须实现IEnumerable接口

 

/// 迭带器---枚举对象并非必须实现IEnumerable接口
/// 迭带器这一节看了足足有两天多的时间。说心里话我都看恶心了
/// 现在终于看明白了一点点。现在把自己理解的东西写出来,主要
/// 是怕以后忘记了,真的不想重头再理解一次了。现在脑袋都迷迷
/// 糊糊的。进入正题吧:
/// 一个类的实例实现了System.Collections.IEnumerable接口那么
/// 这个对象就是可枚举对象
/// 一个类的实例实现了System.Collections.IEnumerator接口那么
/// 这个对象就是枚举器
/// 当程序执行过程中进行迭带的时候,是通过IEnumerator接口的两
/// 个方法以及一个属性配合使用来实现的
/// 两个方法是:
/// MoveNext() 方法 返回一个boolean类型数据用于确定是否迭带至
/// 枚举对象的尾部和迭带的记数累加
/// ReSet()方法,是将枚举对象记数器进行归零
/// 一个属性是:
/// Current属性,用于根据当前记数器得到当前索引位置枚举的的数
/// 据。
/// 进行迭带的时候可以使用两种方法:
/// 1.foreach (string s in pp.GetIenumerator)
/// 2.System.Collections.IEnumerator e = p.GetEnumerator();
///   while (e.MoveNext())
/// 一种是foreach一种是While使用IEnumerator接口的一个方法和一
/// 个属性。其实foreach和while两种方法在IL代码中实现是一样的。
/// 下面来说一下枚举的执行过程。这个是很重要的,我在理解的过
/// 程中不得不使用F11单步执行才能一点点的理解,如果你看了下面
/// 我写的东西也不是很理解的话,可以将下面的代码复制进控制台,
/// 然后进行单步执行。一点点的看应当可以理解,进入正题:
/// 第一步,先得到一个将要进行迭带对象的实例。
/// 第二步,使用foreach或while进行迭带的时候首先从将要进行迭带
/// 的对象中找到实现IEnumerable接口的属性,这个属性的名称是GetEnumerator
/// 这个属性返回了一个实现了IEnumerator接口的类型的实例。如:
/// return new PersonsIenumerable(this);
/// 第三步,使用实现了IEnumerator接口的类型的实例调用IEnumerator
/// 接口中定义的两个方法(MoveNext()、ReSet())和一个属性(Current)
/// 进行迭带动作。
/// 我上面说的如果看不明白的话,那么下面的代码可以进行单步执行,
/// 我想应当可以看明白。
///

///创建一个类,此类构造方法接受一个字符串集合,并且此字符串可以
///进行迭带
class Persons
{
    /// <summary>
    /// 迭带器类(实现了System.Collections.IEnumerator接口)
    /// </summary>
    class PersonsIEnumerator:System.Collections.IEnumerator
    {

        private int index = -1;

        private Persons p;

        public PersonsIEnumerator(Persons pp)
        {
            p = pp;
        }
        #region IEnumerator 成员

        public object Current
        {
            get { return p.m_name[index]; }
        }

        public bool MoveNext()
        {
            index++;
            return index < p.m_name.Length;
        }

        public void Reset()
        {
            index = -1;
        }

        #endregion
    }

    /// <summary>
    /// 可枚举类(此类实现了System.Collections.IEnumerable接口,
    /// 接口中有GetEnumerator()方法)
    /// </summary>
    public class PersonsIenumerable:System.Collections.IEnumerable
    {

        Persons p;
        public PersonsIenumerable(Persons pp)
        {
            p = pp;
        }

        #region IEnumerable 成员

        public System.Collections.IEnumerator GetEnumerator()
        {
            return new PersonsIEnumerator(p);
        }

        #endregion
    }

    /// <summary>
    /// GetIenumerator属性,此属性返回一个枚举对象的实例
    /// return new PersonsIenumerable(this);
    /// </summary>
    internal System.Collections.IEnumerable GetIenumerator
    {
        get { return new PersonsIenumerable(this); }
    }


    string[] m_name;
    public Persons(params string[] sss)
    {
        m_name = new string[sss.Length];
        sss.CopyTo(m_name, 0);
    }

    /// <summary>
    /// 入口Main方法
    /// </summary>
    static void Main()
    {
        ///创建Persons类的一个实例,它的参数是可以进行枚举的
        Persons pp = new Persons("1", "2", "3", "4", "5");
        ///使用迭带器遍历
        foreach (string s in pp.GetIenumerator)
        {
            System.Console.WriteLine(s);
        }

        ///分割线
        System.Console.WriteLine("_____________________________");

        ///创建一个Persons类的一个实例,它的参数是可以进行枚举的
        Persons pp2 = new Persons("a", "b", "c", "d", "e");
        ///根据Persons类的对象实例pp2的属性GetIenumerator得到实现了
        ///IEnumerable接口的PersonsIenumerable类实例
        PersonsIenumerable p = (PersonsIenumerable)pp2.GetIenumerator;
        ///根据PersonsIenumerable实例的GetEnumerator()方法得到实现了
        ///IEnumerator接口的对象实例
        System.Collections.IEnumerator e = p.GetEnumerator();
        ///使用实现了System.Collections.IEnumerator接口的对象实例进
        ///行迭带
        while (e.MoveNext())
        {
            System.Console.WriteLine((string)e.Current);
        }
        ///主线程挂起
        System.Console.ReadLine();
    }
}

 

 

原创粉丝点击