1.首先我们看下IEnumerable接口定义:

  namespace System.Collections  
 {  
     // Summary:  
     //     Exposes the enumerator, which supports a simple iteration over a non-generic  
     //     collection.  
     [ComVisible(true)]  
     [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]  
     public interface IEnumerable  
     {  
         // Summary:  
         //     Returns an enumerator that iterates through a collection.  
         //  
         // Returns:  
         //     An System.Collections.IEnumerator object that can be used to iterate through  
         //     the collection.  
         [DispId(-4)]  
         IEnumerator GetEnumerator();  
     }  
 } 

 

这个接口是重中之重,迭代器就是实现这个接口才能使之迭代的。

2.C#的yield关键字您也必须知道
yield在迭代器块中用于向枚举数对象提供值或发出迭代结束信号。它有两种表现形式:
yield return <expression>;
yield break;

请注意:
expression 必须可以隐式转换为迭代器的 yield 类型
yield语句只能主线在迭代模块中,而不能出现在不安全模块,也不能出现在匿名方法中;当和 expression 一起使用时,yield return 语句不能出现在 catch 块中或含有一个或多个 catch 子句的 try 块中。

3.介绍迭代器概念
其实所谓迭代就是指循环,迭代器是指实现该循环的一种方式。
迭代器是C#2.0增加的功能,它可以是方法、get访问器或运算符,最终它可以使您能够在类或结构中支持foreach迭代。在实现上您不必实现整个IEnumerable接口,您只需提供一个迭代器即可,当编译器监测到迭代器时间,她会自动生成IEnumerable 或 IEnumerable<T> 接口的 Current、MoveNext 和 Dispose 方法。
迭代器是可以返回相同类型的值的有序序列的一段代码,它使用yield return语句一次返回每个元素,使用yield break终止迭代,它的返回类型必须是IEnumerable、 IEnumerator、IEnumerable<T> 或 IEnumerator<T>。

3.创建迭代器最常用的方法是实现IEnumerable接口中的GetEnumerator方法,IEnumerable接口如下:

 using System;  
 using System.Collections;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
   
 namespace ctochina.net  
 {  
     class Program  
     {  
         static void Main(string[] args)  
         {  
             MyIterator myIterator = new MyIterator();  
   
             foreach (int i in myIterator)  
             {  
                 Console.WriteLine(i);  
             }  
         }  
     }  
   
     public class MyIterator  
     {  
         public IEnumerator GetEnumerator()  
         {   
             for(int i=1;i<8;i++)  
             {  
                 yield return i;  
             }  
         }  
     }  
   
 } 
 

输出:
1       2       3       4       5       6       7

注意System.Collections;命名空间的引用,因为IEnumerator在其中
由于是实现IEnumerable接口中的GetEnumerator方法,所以一个类中只能有一个GetEnumerator迭代。

4.另一种实现迭代的方法,代码接着上例如:

 using System;  
 using System.Collections;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
   
 namespace ctochina.net  
 {  
     class Program  
     {  
         static void Main(string[] args)  
         {  
             MyIterator myIterator = new MyIterator();  
               
             //迭代一  
             foreach (int i in myIterator)  
             {  
                 Console.Write(i+"\t");  
             }  
   
             Console.WriteLine();  
   
             //迭代二  
             foreach (int i in myIterator.MyEnumerator_instance(2,8))  
             {  
                 Console.Write(i + "\t");  
             }  
   
             Console.WriteLine();  
   
             //迭代三  
             foreach (int i in MyIterator.MyEnumerator_static(2,8))  
             {  
                 Console.Write(i + "\t");  
             }  
   
         }  
     }  
   
     public class MyIterator  
     {  
         //实现 IEnumerable 接口的 GetEnumerator 方法来实现迭代  
         public IEnumerator GetEnumerator()  
         {   
             for(int i=1;i<8;i++)  
             {  
                 yield return i;  
             }  
         }  
   
         //IEnumerable 的实例实现迭代  
         public IEnumerable MyEnumerator_instance(int iLoop, int jLoop)  
         {   
             for(;iLoop<=jLoop;iLoop++)  
             {  
                 yield return iLoop;  
             }  
         }  
   
         //IEnumerable 的静态实现迭代  
         public static IEnumerable MyEnumerator_static(int iLoop,int jLoop)  
         {  
             for (; iLoop <= jLoop; iLoop++)  
             {  
                 yield return iLoop;  
             }  
         }  
     }  
   
 } 
 

输出:
1       2       3       4       5       6       7
2       3       4       5       6       7       8
2       3       4       5       6       7       8
可见这种方式灵活,一个类中可以有多个迭代的实现

C#中迭代器的概念和两种实现方式的更多相关文章

  1. Ajax中的get和post两种请求方式的异同

    Ajax中我们经常用到get和post请求.那么什么时候用get请求,什么时候用post方式请求呢? 在做回答前我们首先要了解get和post的区别.   1. get是把参数数据队列加到提交表单的A ...

  2. Hibernate中双向多对多的两种配置方式

    Hibernate中双向多对多的两种配置方式 1.建立多对多双向关联关系 package cn.happy.entitys; import java.util.HashSet; import java ...

  3. MyBatis中主键回填的两种实现方式

    主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,无论是 Jdbc 还是各种各样的数据库框架都对此提供了相关的支持,本文我就来和和大 ...

  4. 转:Ajax中的get和post两种请求方式的异同

    1. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML ...

  5. IOC容器在web容器中初始化——(一)两种配置方式

    参考文章http://blog.csdn.net/liuganggao/article/details/44083817,http://blog.csdn.net/u013185616/article ...

  6. Spring 详解(二)------- AOP关键概念以及两种实现方式

    目录 1. AOP 关键词 2. AOP 的作用 3. AOP 的通知类型 4. 基于 xml 的配置方式 5. 基于注解的配置方式 6. 切面的优先级 7. 重用切点表达式 8. 两种方式的比较(摘 ...

  7. jenkins中slave节点连接的两种常用方式

    我们在使用jenkins的时候,一般来说肯定是有slave节点的,本来网上也有好多关于jenkins节点配置的教程,我也就不写了.简单说明一下:任务一般是在slave上面运行的.当然不是讲master ...

  8. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  9. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

随机推荐

  1. SpringMVC加载.roperties文件属性值的方法?

    1.在xml文件中引入来获取属性值就不说了. 2.在controller层获取引用配置文件中的属性值: (1).编写工具类 @Configuration @PropertySource(value=& ...

  2. nodejs后台集成富文本编辑器(ueditor)

    1 下载ueditor nodejs版本 2 复制public目录下面的文件 到项目静态资源public文件夹下 3 在项目根目录创建ueditor文件夹 要复制进来的内容为 4 在根目录的 uedi ...

  3. java Web Servlet学习笔记-1 HttpServletQequest对象的学习

     HttpServletQequest对象的学习 HttpServletRequest HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求 ...

  4. Java API 常用类(一)

    Java API 常用类 super类详解 "super"关键字代表父类对象.通过使用super关键字,可以访问父类的属性或方法,也可以在子类构造方法中调用父类的构造方法,以便初始 ...

  5. HttpHelper类使用方法

    HttpHelper http = new HttpHelper(); HttpItem item = new HttpItem() { URL = "http://www.sufeinet ...

  6. Sqlite常用sql语句

    sqlite常用sql语句 --返回UTC时间 select CURRENT_TIMESTAMP; --返回本地时间 select datetime(CURRENT_TIMESTAMP,'localt ...

  7. WPF控件 在XP下获得焦点有虚线框

    所有 Button.ListBox等控件获得焦点时有虚线框.如图:选中523这个按钮就出线虚框. 我在App.xaml中添加适应所有按钮的样式,无效 <Style  TargetType=&qu ...

  8. 用javascript和html5做一个音乐播放器,附带源码

    效果图: 实现的功能 1.首页 2.底部播放控件 3.播放页面 4.播放列表 5.排行榜 6.音乐搜索 输入搜索关键词,点击放大镜图标 7.侧边栏 目录结构 开发心得与总结 1.轮播图 首先感谢作者S ...

  9. UVa11212,Editing a Book

    正如书上所说,本题需要用IDA*算法求解 启发函数是3d+h>3maxd(d为当前操作步骤数,h为当前逆序对数,maxd为当前枚举的最大步骤数) 可见迭代递归的核心思想是枚举ans去dfs是否可 ...

  10. Linux入门(4)——Ubuntu16.04安装MATLAB2016b

    通常有三个安装文件: Matlab 2016b Linux64 Crack.rar R2016b_glnxa64_dvd1.iso R2016b_glnxa64_dvd2.iso sudo apt i ...