什么时候可以使用yield的关键字来定义迭代器?

  • 迭代器的返回类型必须是IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>
  • 迭代器的入参不能包括ref或out类型的参数

首先,我们定义一个简单的遍历。

        static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person { SaySome = "Hello World,I am Sheldon" });
persons.Add(new Person { SaySome = "Hello World,I am Penny" });
persons.Add(new Person { SaySome = "Hello World,I am Amy" });
foreach (var item in persons)
{
Console.WriteLine(item.SaySome);
}
}

它的输出结果:

接下来,我们使用yield,来实现同样的效果。

        static void Main(string[] args)
{
foreach (var item in GetEnumerator())
{
Console.WriteLine(item.SaySome);
}
} public static IEnumerable<Person> GetEnumerator()
{
yield return new Person { SaySome = "Hello World,I am Sheldon" };
yield return new Person { SaySome = "Hello World,I am Penny" };
yield return new Person { SaySome = "Hello World,I am Amy" };
}

虽然,我们得到了同样的结果,但是yield到底是如何做到的?

(又是翻书,又是看msdn,终于得到了答案)

使用yield语句时,它会自动生成一个枚举器,而不是仅仅生成一个包含项的列表。

——————————————————    以上内容关于yield描述了大概    ———————————————————————

——————————————————以下内容主要说明foreach如何迭代———————————————————————

这个枚举器通过foreach调用,foreach中依次访问每一项时,就会访问这个枚举器,从而达到迭代大量数据,而无须一次把所有的数据写到内存中。

关于枚举器,我查看了system.collection.generic空间下的源码。

为了知道foreach中是如何通过枚举器来工作的。

我们来根据上面的List集合声明一个简单的枚举器

(这个枚举器,只是为了简单的说明一下问题)

public class GameMoves
{
private IEnumerator cross;
private IEnumerator circle;
public GameMoves()
{
cross = Cross();
circle = Circle();
}
private int move = ;
const int MaxMoves = ;
public IEnumerator Cross()
{
while (true)
{
Console.WriteLine("Cross, move {0}", move);
if (++move >= MaxMoves)
{
yield break;
}
yield return circle;
}
}
public IEnumerator Circle()
{
while (true)
{
Console.WriteLine("Circle,move{0}",move);
if (++move>=MaxMoves)
{
yield break;
}
yield return cross;
}
}
}

重写一下Main方法

            var game = new GameMoves();
//将枚举器设置为由game.Cross()返回的枚举器类型
IEnumerator enumerator = game.Cross();
//第一次调用 MoveNext()时,会调用Cross()方法,Cross()方法使用yield返回另一个枚举器
while (enumerator.MoveNext())
{
//返回的值可以用Current属性访问,并设置为enumerator变量,用于下一次循环
enumerator = enumerator.Current as IEnumerator;
}

通过上面的例子我们能看出使用while来变向说明foreach的内部执行方式。

通过 foreach 语句或 LINQ 查询来使用迭代器方法。

foreach 循环的每次迭代都会调用迭代器方法。 迭代器方法运行到 yield return 语句时,会返回一个 expression,并保留当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。

(部分源自msdn)

C#基础知识 yield与foreach的更多相关文章

  1. C#基础知识---迭代器与Foreach语句

    一.Foreach语句简介 在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而如果一个集合要支持使用foreach语句来进行遍历,这个集合一般需要IEnumerable或IEnum ...

  2. C# 基础知识总结

    要学好C#,基础知识的重要性不言而喻,现将常用到的一些基础进行总结,总结如下: 1. 数据类型转换: 强制类型转换(Chart--> int):  char cr='A';   int i = ...

  3. Java 基础知识总结

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.数据类型:  数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte  8位   (by ...

  4. Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

  5. 毕向东—Java基础知识总结(超级经典)

    Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...

  6. C#基础知识汇总(不断更新中)

    ------------------------------目录---------------------------- 1.隐式类型2.匿名类型3.自动属性4.初始化器5.委托6.泛型7.泛型委托8 ...

  7. Java 基础知识总结1

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.数据类型:  数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte  8位   (by ...

  8. Linq的简介和基础知识学习

    学习LINQ之前,我们要知道LINQ是干什么,解决什么问题的,怎样学习? 一.LINQ简介 1.什么是LINQ? 什么是LINQ?LINQ中文翻译为语言集成查询(Language Integrated ...

  9. 黑马毕向东Java基础知识总结

    Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记    侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...

随机推荐

  1. 巧用ecshop做淘宝客

    一.第一步 下载文件,可以在http://www.ecshop.com/下载ecshop各个版本的安装包,安装好ECSHOP,然后通过PTF工具下载2个文件到本地进行修改.这个2个文件分别是goods ...

  2. 如何在C#中使用存储过程(SQL Server 2000)

    要在C#中使用存储过程,首先看看test表的创建sql语句:   create table test55 ( uid int identity(1,1), class1 varchar(20), cl ...

  3. c# 实体类生成工具

    一个简单生成c#实体类的工具 源代码下载

  4. 使用Supervisor守护Python进程

    1.需求 现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,就需要使用到了Supervisor.Supervisor起到守护 ...

  5. 手 Q 人脸识别动画实现详解

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 前言 开门见山,先来看下效果吧. 看到这么酷炫的效果图,不得不赞叹一下我们的设计师.然而,站在程序员的角度上看,除了酷炫之外更多的是复杂.但是 ...

  6. Python [习题] 字典排序

    [习题] 对此字典分别按照value 和key 如何排序? dic1 = {'and':40, 'a':54, 'is':60, 'path':139, 'the':124, 'os':49} In ...

  7. 开始你的第一个npm脚本工具

    在实际开发中,一般刚开始一个项目或者刚接手一个项目,我们会运行 npm install 下载安装所有依赖, 在实际开发中,可能也会使用各种命令行-- 来提高我们开发的效率. 与它相处了这么久,你真的了 ...

  8. 内网神器-Bettercap

    安装bettercap 1 2 root@sch01ar:~# apt-get update root@sch01ar:~#  apt-get install bettercap 安装完成后查看一下帮 ...

  9. robotframework文本类型的下拉框

    对于下拉框定位和输入,这里主要遇到有两种类型的下拉选择. 其中一个类型是select-options格式,如图 这种方式的定位可以使用select from list by value或select ...

  10. c语言贪吃蛇详解3.让蛇动起来

    c语言贪吃蛇详解3.让蛇动起来 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 上次 ...