zoukankan      html  css  js  c++  java
  • IEnumerator和IEnumerable详解

    https://www.cnblogs.com/cjm123/p/8671783.html


    5

    代码达到了遍历效果,但是在用foreach遍历时,IEnumerator和IEnumerable究竟是如何运行的,我们可以通过增加增加日志可以直观的看到原因。

    //一个常量的数组,用于foreach遍历
    class ConstArrayList : IEnumerable
    {
        public int[] constItems = new int[] { 1, 2, 3, 4, 5 };
        public IEnumerator GetEnumerator()
        {
            WriteLine("GetIEnumerator");
            return new ConstArrayListEnumeratorSimple(this);
        }
    }
    //这个常量数组的迭代器
    class ConstArrayListEnumeratorSimple : IEnumerator
    {
        ConstArrayList list;
        int index;
        int currentElement;
        public ConstArrayListEnumeratorSimple(ConstArrayList _list)
        {
            list = _list;
            index = -1;
        }
    
        public object Current
        {
            get
            {
                WriteLine("Current");
                return currentElement;
            }
        }
    
        public bool MoveNext()
        {
            if(index < list.constItems.Length - 1)
            {
                WriteLine("MoveNext true");   
                currentElement = list.constItems[++index];
                return true;
            }
            else
            {
                WriteLine("MoveNext false");
                currentElement = -1;
                return false;
            }
        }
    
        public void Reset()
        {
            WriteLine("Reset");
            index = -1;
        }
    }
    class Program
    {    
        static void Main(string[] args)
        {
            ConstArrayList constArrayList = new ConstArrayList();
            foreach(int item in constArrayList)
            {
                WriteLine(item);
            }
            ReadKey();
        }
    }

    输出结果:
    GetIEnumerator
    MoveNext true
    Current
    1
    MoveNext true
    Current
    2
    MoveNext true
    Current
    3
    MoveNext true
    Current
    4
    MoveNext true
    Current
    5
    MoveNext false

    通过输出结果,我们可以发现,foreach在运行时会先调用ConstArrayList的GetIEnumerator函数获取一个ConstArrayListEnumeratorSimple,之后通过循环调用ConstArrayListEnumeratorSimple的MoveNext函数,index后移,更新Current属性,然后返回Current属性,直到MoveNext返回false。

    总结一下:
    GetIEnumerator()负责获取枚举器。
    MoveNext()负责让Current获取下一个值,并判断遍历是否结束。
    Current负责返回当前指向的值。
    Rest()负责重置枚举器的状态(在foreach中没有用到)
    这些就是IEnumerable,IEnumerator的基本工作原理了。

    其次我们发现:

    ConstArrayList constArrayList = new ConstArrayList();
    foreach(int item in constArrayList)
    {
        writeLine(item);
    }

    其实就等价于:

    ConstArrayList constArrayList = new ConstArrayList();
    IEnumerator enumeratorSimple = constArrayList.GetEnumerator();
    while (enumeratorSimple.MoveNext())
    {
        int item = (int)enumeratorSimple.Current;
        WriteLine(item);
    }

    也就是说foreach其实是一种语法糖,用来简化对可枚举元素的遍历代码。而被遍历的类通过实现IEnumerable接口和一个相关的IEnumerator枚举器来实现遍历功能。

  • 相关阅读:
    DOS net use
    DOS cscript
    DOS bcp
    DOS ftp
    java 锁机制(synchronized 与 Lock)
    java-过滤器(Filter)
    java collection集合
    java Map集合对比分析
    java反射与注解结合使用(根据传入对象输出查询sql)
    java反射-使用反射来操纵方法
  • 原文地址:https://www.cnblogs.com/gaoxianzhi/p/11949133.html
Copyright © 2011-2022 走看看