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

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

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

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

该接口的方法

public interface IEnumerable

    {

        // 摘要:

        //     返回一个循环访问集合的枚举数。

        //

        // 返回结果:

        //     一个可用于循环访问集合的 System.Collections.IEnumerator 对象。

        [DispId(-)]

        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默认将集合的索引指向前一个

        ;

        //05实现接口的Movenext方法

        public bool MoveNext()

        {

            bool happy = false;//默认为没有数据

             > index)

            {

                //证明集合中有数据让索引加1

                index++;

                //改变bool值为true

                happy = true;

            }

            return happy;

        }

        public void Reset()

        {

            index = -;

        }

    }
 MyList list=new MyList();

     list.Add("小王");

     list.Add("小李");

     foreach (string item in list)

     {

         Console.WriteLine(item);

      }

    Console.ReadKey();

探讨关于C#中Foreach的本质的更多相关文章

  1. 接口、索引器、Foreach的本质(学习笔记)

    接口 什么是接口? 接口代表一种能力,和抽象类类似但比抽象类的抽象程度更高! 接口的定义: public interface IEat//定义一个接口 { void Eat(string food); ...

  2. C#中foreach的实现原理

    C#中foreach的实现原理 在探讨foreach如何内部如何实现这个问题之前,我们需要理解两个C#里边的接口,IEnumerable 与 IEnumerator. 在C#里边的遍历集合时用到的相关 ...

  3. ecshop中foreach的详细用法归纳

    ec模版中foreach的常见用法. foreach 语法: 假如后台:$smarty->assign('test',$test); {foreach from=$test item=list ...

  4. mybatis中foreach的用法(转)

    foreach一共有三种类型,分别为List,[](array),Map三种. foreach属性 属性 描述 item 循环体中的具体对象.支持属性的点路径访问,如item.age,item.inf ...

  5. thinkphp模板中foreach循环没数据的错误解决

    从控制器方法中$this->assign();函数将值传递给html模板 但是模板不显示数据,直接出来的是代码,效果就和html中写了php代码不能解析一样. 原来是我将thinkphp框架的引 ...

  6. c语言中函数调用的本质从汇编角度分析

    今天下午写篇博客吧,分析分析c语言中函数调用的本质,首先我们知道c语言中函数的本质就是一段代码,但是给这段代码起了一个名字,这个名字就是他的的这段代码的开始地址 这也是函数名的本质,其实也就是汇编中的 ...

  7. php中foreach()函数与Array数组经典案例讲解

    //php中foreach()函数与Array数组经典案例讲解 function getVal($v) { return $v; //可以加任意检查代码,列入要求$v必须是数字,或过滤非法字符串等.} ...

  8. PHP中foreach()用法汇总

    这篇文章主要给大家详细介绍了PHP中foreach()用法以及相关的示例,十分的细致,有需要的小伙伴可以参考下. PHP 4 引入了 foreach 结构,和 Perl 以及其他语言很像.这只是一种遍 ...

  9. flask中路由的本质源码分析

    flask中url的本质: 吧url和视图函数封装到一个Rule对象里面去了,并且吧这个对象添加到url_map中 Rule={"url":'/index','method':'i ...

随机推荐

  1. PRML读书会第二章 Probability Distributions(贝塔-二项式、狄利克雷-多项式共轭、高斯分布、指数族等)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:11:56 开始吧,先不要发言了,先讲PRML第二章Probability Dis ...

  2. C#对 Dictionary进行排序 转

    C# .net 3.5 以上的版本引入 Linq 后,字典Dictionary排序变得十分简单,用一句类似 sql 数据库查询语句即可搞定:不过,.net 2.0 排序要稍微麻烦一点,为便于使用,将总 ...

  3. split 方法的正确使用姿势

    本文同步自我的个人博客:http://www.52cik.com/2015/11/02/split-skill.html 通过js获取 QueryString (location.search部分) ...

  4. mac使用笔记

    1.QQ多开 MAC中登录QQ后按CMD+N组合按键即可新打开一个QQ登录窗口 2.关闭左右摇晃鼠标放大 系统偏好设置>辅助功能>显示器,去掉“摇动鼠标以定位”前面的勾即可 3.使用ctr ...

  5. 4G时代的抢钱之道

    最近最大的事件恐怕就是移动的4G上线了,50元600M起计价,上网速度最高理论到达100Mbps,相当于一秒下载10MB的数据,或者是一分钟下载一张VCD(600M)电影. 当然,对于这样的流量套餐, ...

  6. JAVA package-info文件【转】

    翻看以前的笔记,看到一个特殊的java文件:pacakge-info.java,虽然有记录,但是不全,就尝试着追踪一下该问题, 分享一下流水账式的结果. 首先,它不能随便被创建.在Eclipse中, ...

  7. 更新java对xml文件的操作

    //更新java在xml文件中操作的内容 public static void upda(Document doc) throws Exception{ //创建一个TransformerFactor ...

  8. Handlebars的使用方法文档整理(Handlebars.js)

    Handlebars是一款很高效的模版引擎,提供语意化的模版语句,最大的兼容Mustache模版引擎, 提供最大的Mustache模版引擎兼容, 无需学习新语法即可使用; Handlebars.js和 ...

  9. Java异常-一般异常和运行时异常的区别

    Java提供了两类主要的异常:runtime exception和checked exception.checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常.对于这种异常, JA ...

  10. meta之renderer

    今天不小心看了下慕课网首页的源码,看到有一行 1 <meta name="renderer" content="webkit|ie-comp|ie-stand&qu ...