C#基础知识 yield与foreach
什么时候可以使用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的更多相关文章
- C#基础知识---迭代器与Foreach语句
一.Foreach语句简介 在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而如果一个集合要支持使用foreach语句来进行遍历,这个集合一般需要IEnumerable或IEnum ...
- C# 基础知识总结
要学好C#,基础知识的重要性不言而喻,现将常用到的一些基础进行总结,总结如下: 1. 数据类型转换: 强制类型转换(Chart--> int): char cr='A'; int i = ...
- Java 基础知识总结
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.数据类型: 数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte 8位 (by ...
- Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
- 毕向东—Java基础知识总结(超级经典)
Java基础知识总结(超级经典) 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部分用到哪些语句,方法,和对象. 4,代码实现.用具体的java ...
- C#基础知识汇总(不断更新中)
------------------------------目录---------------------------- 1.隐式类型2.匿名类型3.自动属性4.初始化器5.委托6.泛型7.泛型委托8 ...
- Java 基础知识总结1
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.数据类型: 数据类型:1>.基本数据类型:1).数值型: 1}.整型类型(byte 8位 (by ...
- Linq的简介和基础知识学习
学习LINQ之前,我们要知道LINQ是干什么,解决什么问题的,怎样学习? 一.LINQ简介 1.什么是LINQ? 什么是LINQ?LINQ中文翻译为语言集成查询(Language Integrated ...
- 黑马毕向东Java基础知识总结
Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记 侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...
随机推荐
- C# Dapper 轻量ORM调试对SQLServer
Dapper简介 Dapper只有一个代码文件,完全开源,你可以放在项目里的任何位置,来实现数据到对象的ORM操作,体积小速度快. 使用ORM的好处是增.删.改很快,不用自己写sql,因为这都是重复技 ...
- C#.NET 用程序画图,曲线图
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security ...
- python基础-------函数(三)
迭代器 一.迭代的概念 迭代:1 重复2 下一次重复是基于上一次的结果 l=['a','b','c','d'] count=0while count < len(l): print(l[coun ...
- Winform界面中实现菜单列表的动态个性化配置管理
在我们一般的应用系统里面,由于系统是面向不同类型的用户,我们所看到的菜单会越来越多,多一点的甚至上百个,但是我们实际工作接触的菜单可能就是那么几个,那么对于这种庞大的菜单体系,寻找起来非常不便.因此对 ...
- 关于如何获取移动端 touchmove 事件中真正触摸点下方的元素
移动端的touchstart, touchmove, touchend三个事件,点击元素并拖动时,获取到了touchmove事件, 但是event.touches[0].target所指向的元素却是t ...
- Openning
In order to imporve my english writing skill and enhance my understanding of programming ,I'm setti ...
- 一位有着工匠精神的博主写的关于IEnumerable接口的详细解析
在此,推荐一位有着工匠精神的博主写的一篇关于IEnumerable接口的深入解析的文章:http://www.cnblogs.com/zhaopei/p/5769782.html#autoid-0-0 ...
- 个人笔记之json实现模糊查询
1:首先创建一个项目如:(说明:此项目是在eclipse创建的) 2.在创建相对应的包如: 3.创建写好相对应的配置文件如: applicationContext.xml具体内容如下: <?xm ...
- jdk1.8hashmap源码解析
/* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETA ...
- Python中的选择排序
选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大 ...