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. zoj 1889 ones 数学

    Ones Time Limit: 2 Seconds      Memory Limit: 65536 KB Given any integer 0 <= n <= 10000 not d ...

  2. RewriteMap(apache)

    最近在工作中发现一个陌生的语法,apache服务器站点rewrite配置文件里的,开始还以为是apache的一种新语法,以这个词网上搜索,没搜到相关文章,跟老同事请教了一下,说这个是RewriteMa ...

  3. Echarts数据可视化polar极坐标系,开发全解+完美注释

    全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...

  4. iOS开发必不可少的76个工具

    如果你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完成不同的任务. 软件开发同样如此.你可以从软件开发者如何使用工具中看出他水准如何.有经验的开发者精于使用工具.对你目前所使用的工具不断 ...

  5. 移动端自动化自动化(Android&iOS)——Appium

    Appium-Python 移动端自动化环境搭建 Appium介绍 Appium是一个开源.跨平台的测试框架,可以用来测试原生及混合的移动端应用.Appium支持iOS.Android及Firefox ...

  6. 压缩感知“Hello World”代码初步学习

    压缩感知代码初学 实现:1-D信号压缩传感的实现 算法:正交匹配追踪法OMP(Orthogonal Matching Pursuit)   >几个初学问题   1. 原始信号f是什么?我采集的是 ...

  7. Shell一个文件并等待完成

    Option Explicit Private Declare Function OpenProcess Lib "kernel32" _ (ByVal dwDesiredAcce ...

  8. Delphi实现电脑端微信图片文件解密

    电脑端微信收到图片后是存在了“C:\Users\系统用户名\Documents\WeChat Files\微信帐号\Data”目录下的,但文件不能直接使用图片浏览器打开的,因为做了一些加密,之前有个朋 ...

  9. win10 uwp 打开文件管理器选择文件

    本文:让文件管理器选择文件,不是从文件管理器获得文件. 假如已经获得一些文件,那么如何从文件管理器选择这些文件? 使用方法很简单. 从网上拿图来说 打开文件夹自动选择所有文件 首先需要获得文件夹,因为 ...

  10. Python程序练习4--模拟员工信息数据库操作

    1.功能简介 此程序模拟员工信息数据库操作,按照语法输入指令即能实现员工信息的增.删.改.查功能.   2.实现方法 架构: 本程序采用python语言编写,关键在于指令的解析和执行:其中指令解析主要 ...