C# foreach遍历原理-创建枚举器实现遍历(不使用foreach,实现遍历)

昨天看了一下foreach实现原理(通过创建枚举器),今天将知识汇总下方便以后回头看看,同时希望可以帮到更多的人。

废话不多说,上正式解释。


其实通过foreach遍历数据,实际上是调用了一个“枚举器”来遍历数据,和foreach一点关系都没有,而foreach只是语法上的一个简化而已。写foreach只是降低枚举的复杂度,使程序员不用自己写复杂的遍历逻辑,只用调用foreach即可实现。

但是想我们这样不平凡的人,怎么甘愿总用着foreach却不懂其原理呢!  哈哈

上代码:

namespace FanXing
{
    // 需要让该类型实现一个叫IEnumerable的接口,并重写GetEnumerator方法(注意重写完此方法后,接口可删除。其实需要的不是这个接口而是这个方法)
    class ForeachFX : IEnumerable
    {
        string[] m_love = new string[] { "理智", "林青霞", "李若彤", "刘亦菲" };

        // 这个方法的作用是获取一个枚举器
        public IEnumerator GetEnumerator()

        {

            return new ForeachEnumerator(this.m_love); // return一个ForeachEnumerator对象
            //throw new NotImplementedException();
        }
    }

    // 这个类型就是一个枚举器
    class ForeachEnumerator : IEnumerator
    {
        string[] m_love = null;
        int index = -1; // 根据索引下标遍历数组,注意:下标一般都起到开始的前一个

        public ForeachEnumerator(string[] m_love)
        {
            this.m_love = m_love;
        }

        public object Current // 当前值。如其所是为object类型
        {
            get
            {
                if(index >= 0 && index < m_love.Length)
                {
                    return m_love[index];
                }else
                {
                    throw new IndexOutOfRangeException();
                }
            }
        }

        public bool MoveNext() // 获取下一个
        {
            if(index + 1 < m_love.Length)
            {
                index++;
                return true;
            }
            return false;
            //throw new NotImplementedException();
        }

        public void Reset() // 将index重置为-1
        {
            index = -1;
        }
    }

}


main 函数代码:

ForeachFX foreachfx = new ForeachFX();
            // 调用GetEnumerator方法,返回ForeachEnumerator对象传给IEnumerator
            IEnumerator ienumerator = foreachfx.GetEnumerator();
            while (ienumerator.MoveNext()) // 调用MoveNext()方法,进行下一个
            {
                // 输出Current
                Console.WriteLine(ienumerator.Current.ToString());
            }
            // 重置,将index重置为-1
            ienumerator.Reset();
            Console.ReadKey();


如以上所示,就创建一个枚举器,通过以上枚举器就可以实现foreach的遍历。而两个类分别继承的IEnumerable、IEnumerator接口,皆可删除。接口中重写的方法才是我们写上接口的目的。

猜你喜欢

转载自blog.csdn.net/IT_choshim/article/details/80769367