yield个人理解及简明示例
1.写法有2种:
yield return <expression>和yield break
yield用于在迭代中返回一个值,并将值带入下一次迭代中。yield break则意味着停止迭代。纯粹的文字描述,一千个人有一千个说法,还是用代码更容易说清楚。
2.官方示例(略带修改):
private void button1_Click(object sender, EventArgs e)
{
string s = string.Empty;
foreach (int i in List.Power(2,8))
{
s += i.ToString() + ",";
}
MessageBox.Show(s);
}
public class List
{
//using System.Collections;
public static IEnumerable Power(int number, int exponent)
{
int counter = 0;
int result = 1; while (counter++ < exponent)
{
result = result * number;
yield return result;
}
}
}
运行示例,发现power方法中的while代码部分,每循环执行一次,即输出一个值,并将这个值带入下一次循环,而power函数并没有每次被调用。
为了验证,我们修改下官方示例代码,来看看我们的判断是否有误:
private void button1_Click(object sender, EventArgs e)
{
string s = string.Empty;
foreach (int i in List.Power())
{
s += i.ToString() + ",";
}
MessageBox.Show(s);
}
public static IEnumerable Power()
{
int counter = 0;
int result = 1;
int number = 2, exponent = 8;
while (counter++ < exponent)
{
result = result * number;
yield return result;
}
}
运行结果与官方示例相同,说明.net framework每次只把yield部分所在的部分代码进行了迭代返回处理。
3.官方的另一个示例为用yield作为属性(输出方式略有修改)。
private void button2_Click(object sender, EventArgs e)
{
var theGalaxies = new Galaxies();
string ps = string.Empty;
foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
{
ps += (theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString() + " >> ");
}
MessageBox.Show(ps);
}
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
} }
输出结果:

从这个例子可以看出yield其实就是临时中断执行,输出后继续执行而已。
可以修改下这个例子,看效果如何:
public class Galaxies
{
List<Galaxy> ls = new List<Galaxy>();
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
} }
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1
{ get
{
ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });
ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });
ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });
ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });
int i = -1;
while (i++ < ls.Count - 1)
{
yield return ls[i];
}
}
}
}
调用NextGalaxy1后,结果与官方示例结果相同,还可以进一步修改NextGalaxy1,使其更容易别理解:
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1
{ get
{
ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });
ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });
ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });
ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });
int i = 0;
while (i < ls.Count)
{
yield return ls[i];
i++;
}
}
}
这样看来就很容易理解其含义了,更进一步说就是一边给你输出结果,一边继续给你执行代码,一举两得!
如果想中断执行,则直接用yield break即可。
代码如下:
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy1
{ get
{
ls.Add(new Galaxy { Name = "Tadpole", MegaLightYears = 400 });
ls.Add(new Galaxy { Name = "Pinwheel", MegaLightYears = 25 });
ls.Add(new Galaxy { Name = "Milky Way", MegaLightYears = 0 });
ls.Add(new Galaxy { Name = "Andromeda", MegaLightYears = 3 });
int i = -1;
while (i++ < ls.Count - 1)
{
yield return ls[i];
if (ls[i].MegaLightYears == 0)
{
yield break;
} }
}
}
输出结果为:

附官方链接:http://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx
yield个人理解及简明示例的更多相关文章
- yield的理解
yield的理解:yield命令是异步两个阶段的分界线需要先对迭代器和生成器进行理解: 迭代器:是一种支持next()操作的对象.它包含一组元素,当执行next()时,返回其中一个元素:当所有元素都被 ...
- [llvm] LLVM 核心类简明示例 : llvm::Value && llvm::Type && llvm::Constant
LLVM 核心类简明示例 : llvm::Value && llvm::Type && llvm::Constant llvm核心类位于 include/llvm/IR ...
- 转载yield关键字理解
实现IEnumerable接口及理解yield关键字 [摘要]本文介绍实现IEnumerable接口及理解yield关键字,并讨论IEnumerable接口如何使得foreach语句可以使用. 本 ...
- C#中yield关键字理解
yield关键字之前用得较少,但是在做项目开发的过程中也遇到了,当时有点迷惑,就顺便研究学习了一下,以下是个人理解,不到之处欢迎拍砖!废话就到这,上代码: class Program { static ...
- 对yield 的理解
最近在学习Python的时候看到yield的相关语法,感觉很独特,相比其他如C/C++的语法比较有意思,于是在看完资料相关章节做一个总结. yield 是一个类似于 return的语法,但是对于ret ...
- 迭代器,生成器,yield,yield from理解
迭代器 说到迭代器就得想说可迭代对象Iterable,实现了__iter__()方法的对象都是可迭代对象,例如很多容器,list ,set, tuples.使用iter方法可以把一个可迭代对象变成迭代 ...
- iOS 浅复制和深复制的深层理解,含示例
转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...
- Python yield函数理解
Python中的yield函数的作用就相当于一个挂起,是不被写入内存的,相当于一个挂起的状态,用的时候迭代,不用的时候就是一个挂起状态,挂起状态会以生成器的状态表现
- Python中yield深入理解
众所周知,python中的yield有这样的用法: def test(alist): for i in alist: yield i 这样,这个test函数就变成了一个生成器,当每次调用的时候,就会自 ...
随机推荐
- Ubuntu下快速安装LAMP server
Ubuntu下可快速安装LAMP server(Apache+MySQL+PHP5). 首先,打开Ubuntu虚拟机,Terminal打开root权限:“sudo -s”. 一.安装LAMP serv ...
- PHP的GD 支持和加载MySQL功能
本机安装dedecms时发现, GD 支持 On [×]Off (不支持将导致与图片相关的大多数功能无法使用或引发警告) MySQL 支持 On [×]Off (不支持无法使用本系统) 错误,原来是环 ...
- 探索javascript----有关数组的常用方法
与字符串的转换: str.split(","):将一个字符串以为英文逗号分割,返回一个数组: arr.join(","):返回用指定分隔符间隔的含所有数组元素的 ...
- windows核心编程---第三章 内核对象及句柄本质
本章讨论的是相对抽象的概念,不涉及任何具体的内核对象的细节而是讨论所有内核对象的共有特性. 首先让我们来了解一下什么是内核对象.内核对象通过API来创建,每个内核对象是一个数据结构,它对应一块内存 ...
- 拔靴法--Bootstrap--R语言实现
拔靴法属于重复抽样(resampling)方法,与Monte Carlo相比,二者真实的母体不同.它是将已有的观察值作为母体重复抽样, 以求取原先资料不足二无法探讨的资料特性. 举个例子,假设x1,x ...
- 一些常用的vim设置
以下内容皆来源于网络,感谢原作者.如果引用出处错误,请告知以便修改. 1. vim的几种模式和按键映射 转载自:[1] Map是Vim强大的一个重要原因,可以自定义各种快捷键,用起来自然得心应手.vi ...
- 传智播客JavaWeb day07、day08-自定义标签(传统标签和简单标签)、mvc设计模式、用户注册登录注销
第七天的课程主要是讲了自定义标签.简单介绍了mvc设计模式.然后做了案例 1. 自定义标签 1.1 为什么要有自定义标签 前面所说的EL.JSTL等技术都是为了提高jsp的可读性.可维护性.方便性而取 ...
- 使用response实现文件的下载
package cn.itcast.request; import java.io.FileInputStream;import java.io.IOException;import java.io. ...
- Spring将多个配置文件引入一个配置文件中
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Linux——常用命令详解
文件处理命令:ls -l drwxr-xr-x 文件 d rwx r-x r-x d:表示directory 是一个目录 - 表示二进制文件 l 表示链接文件l ...