zoukankan      html  css  js  c++  java
  • 探讨关于C#中Foreach的本质

    一.为什么数组和集合可以使用foreach遍历

    01. 因为数组和集合都实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator()

    02.数组类型是从抽象基类型 Array 派生的引用类型。由于此类型实现了 IEnumerable ,因此可以对 C# 中的所有数组使用 foreach 迭代。(摘自MSDN)

     二.探讨针对于List集合微软的是怎么实现这个IEnumerable接口的

    该接口的方法

    public interface IEnumerable
    
        {
    
            // 摘要:
    
            //     返回一个循环访问集合的枚举数。
    
            //
    
            // 返回结果:
    
            //     一个可用于循环访问集合的 System.Collections.IEnumerator 对象。
    
            [DispId(-4)]
    
            IEnumerator GetEnumerator();
    
    }

     

    对于GetEnumerator这个方法他的返回值时又是一个接口类型。所以在这里还要看IEnumerator的接口内容。

    public interface IEnumerator
    
        {
    
            // 摘要:
    
            //     获取集合中的当前元素。
    
            //
    
            // 返回结果:
    
            //     集合中的当前元素。
    
            object Current { get; }
    
     
    
            // 摘要:
    
            //     将枚举数推进到集合的下一个元素。
    
            //
    
            // 返回结果:
    
            //     如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。
    
            //
    
            // 异常:
    
            //   System.InvalidOperationException:
    
            //     在创建了枚举数后集合被修改了。
    
            bool MoveNext();
    
            //
    
            // 摘要:
    
            //     将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
    
            //
    
            // 异常:
    
            //   System.InvalidOperationException:
    
            //     在创建了枚举数后集合被修改了。
    
            void Reset();
    
        }

    所以不难发现微软是通过这种方法的实现遍历迭代变量的

    三.通过C#代码实现自定义类型的集合遍历

    首先该类必须实现IEnumerable接口

     //01自定义类型:实现IEnumerable接口,证明这个类型保存的数据能被foreach遍历
    
        //IEnumberable这个接口,在微软底层有一个方法GetEnumerator()返回值类型是IEnumerator接口
    
        public class MyList:IEnumerable
    
        {
    
            //02定义一个集合
    
            ArrayList list=new ArrayList();
    
            //03实现IEnumberable的方法
    
            public IEnumerator GetEnumerator()
    
            {
    
               return new MyIEnumerator(list);
    
            }
    
     
    
            public void Add(Object oj)
    
            {
    
                list.Add(oj);
    
            }
    
    }
    //IEnumerator:支持对非泛型集合的简单迭代
    
        public class MyIEnumerator:IEnumerator
    
        {
    
            //01定义一个List集合
    
            ArrayList list=new ArrayList();
    
            //02无参构造
    
            public MyIEnumerator(ArrayList list)
    
            {
    
                //跟当前类的集合赋值
    
                this.list = list;
    
            }
    
     
    
            public object Current
    
            {
    
                get { return list[index]; }
    
            }
    
            //04默认将集合的索引指向前一个
    
            private int index = -1;
    
            //05实现接口的Movenext方法
    
            public bool MoveNext()
    
            {
    
                bool happy = false;//默认为没有数据
    
                if (list.Count - 1 > index)
    
                {
    
                    //证明集合中有数据让索引加1
    
                    index++;
    
                    //改变bool值为true
    
                    happy = true;
    
                }
    
                return happy;
    
            }
    
     
    
            public void Reset()
    
            {
    
                index = -1;
    
     
    
            }
    
        }
     MyList list=new MyList();
    
         list.Add("小王");
    
         list.Add("小李");
    
         foreach (string item in list)
    
         {
    
             Console.WriteLine(item);
    
          }
    
        Console.ReadKey();

     

      

     

  • 相关阅读:
    hihoCoder #1176 : 欧拉路·一 (简单)
    228 Summary Ranges 汇总区间
    227 Basic Calculator II 基本计算器II
    226 Invert Binary Tree 翻转二叉树
    225 Implement Stack using Queues 队列实现栈
    224 Basic Calculator 基本计算器
    223 Rectangle Area 矩形面积
    222 Count Complete Tree Nodes 完全二叉树的节点个数
    221 Maximal Square 最大正方形
    220 Contains Duplicate III 存在重复 III
  • 原文地址:https://www.cnblogs.com/hyjj/p/5387103.html
Copyright © 2011-2022 走看看