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. C#.net干货,最全公共帮助类

    比较全面的c#帮助类,日常工作收集,包括前面几家公司用到的,各式各样的几乎都能找到,所有功能性代码都是独立的类,类与类之间没有联系,可以单独引用至项目,分享出来,方便大家,几乎都有注释,喜欢的请点赞, ...

  2. Nginx详细安装部署教程

    一.Nginx简介 Nginx是一个web服务器也可以用来做负载均衡及反向代理使用,目前使用最多的就是负载均衡,具体简介我就不介绍了百度一下有很多,下面直接进入安装步骤 二.Nginx安装 1.下载N ...

  3. install xdebug

    安装准备 安排php的xdebug扩展,在php.ini上配置xdebug.通过phpinfo或者php-m 查看 [Xdebug] zend_extension ="D:\upupw7\P ...

  4. Python系列之反射、面向对象

    一.反射 说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式 1. import commons 2. __import__('commons') 如果是多层导入: ...

  5. Jquery使用mouseenter和mouseleave实现鼠标经过弹出层且可以点击

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jquery使用mousee ...

  6. ASP.NET Core 处理 404 Not Found

    问题 在没有修改任何配置的情况下,这是用户使用 Chrome 访问不存在的URL时会看到的内容: 幸运的是,处理错误状态代码非常简单,我们将在下面介绍三种技术. 解决方案 在以前的ASP.NET MV ...

  7. Install Ubuntu On Windows10(win10上安装linux系统)

    一.准备: 硬件:U盘 软件:ultraiso.Ubuntu镜像文件 二.安装linux: 1.Ubuntu官网(http://www.ubuntu.org.cn/download/alternati ...

  8. win10 uwp 保存用户选择文件夹

    如果我们每次把临时处理的文件保存,都要让用户选择一次,用户会不会觉得uwp垃圾?如果我们每次打开应用,都从某个文件读取,而这个文件不在应用目录和已知的目录,那么每次都需要用户选择,用户会不会觉得uwp ...

  9. JS前端三维地球渲染——中国各城市航空路线展示

    前言 我还从来没有写过有关纯JS的文章(上次的矢量瓦片展示除外,相对较简单.),自己也学习过JS.CSS等前端知识,了解JQuery.React等框架,但是自己艺术天分实在不过关,不太喜欢前端设计,比 ...

  10. IO基础内容(File)

    JavaIO基础内容 IO技术概述 Output 把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作 Input 把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操 ...