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函数就变成了一个生成器,当每次调用的时候,就会自 ...
随机推荐
- iOS开发UI篇—从代码的逐步优化看MVC
iOS开发UI篇—从代码的逐步优化看MVC 一.要求 要求完成下面一个小的应用程序. 二.一步步对代码进行优化 注意:在开发过程中,优化的过程是一步一步进行的.(如果一个人要吃五个包子才能吃饱,那么他 ...
- android 第一个程序的编写
移通152余继彪 需求分析:输入两个数字,让他们相乘,然后得出结果 首先建立一个android项目 在 layout中建立第一个界面 该界面有四个组件,两个editText 一个TextView,一个 ...
- C#面向对象总结1
1.面向过程-----> 面向对象 面向过程:面向的是完成这件事的过程,强调的是完成这件事的动作. 面向对象:找个对象帮你做事. 意在写出一个通用的代码,屏蔽差异. 我们在代码中描述一个对象,一 ...
- Get请求编码
遇到get请求中文编码的时候,有的人会采用在Tomcat/conf/server.xml中的如下添加一句: <Connector port="8080" protocol=& ...
- windows 版的julia repl 启动时间已经大大优化!
julia 是一门语法类似python 偏向主要用于科学计算的语言,julia吸收了很多其它语言的优点,内置了大量函数,使用起来很方便. 之前windows下的 julia repl(交互解释器)启动 ...
- Objective-C学习笔记-第三天(1)
今天开始用oc写iOS程序,遇到的问题有 1.在不同的类使用类的方法或者访问类的属性的时候(公开的方法或者属性),方法或者属性必须在类头文件中声明. 2.对象类型的声明以及定义需要用*,表明这个是一个 ...
- lightoj1030
//Accepted 1688 KB 0 ms //http://kicd.blog.163.com/blog/static/126961911200910168335852/ //链接里的例子讲的很 ...
- iOS-Gdata XML解析配置和简单使用
简单介绍使用废话少说直接上图就能看明白... 导入libxml2,使用第三方AFNetworking网络请求,第三方XML解析GData GData需要的配置 Build Settings 里搜索,添 ...
- 一个共享内存hash
Background 我们的多进程程序碰到一个需求:做key-value查询,然后拿获取到的value去做一些事情.这些key-value存储在很多词典文件中,数量级>10w,如果每个进程都加载 ...
- UVA 572
这是一道纯正的深度优先搜索题目. 题目要求在有多少个不同的块,而不同块的定义则是,一个块中的任意一点和l另一个块中的任意一点不会相连,而相连的定义则是 在横向.纵向和对角线上相连. #include& ...