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函数就变成了一个生成器,当每次调用的时候,就会自 ...
随机推荐
- Hilbert space
Definition A Hilbert space H is a real or complex inner product space that is also a complete metric ...
- 运放——压摆率SR的意义和如何选取
http://blog.csdn.net/dxshappy/article/details/8065798
- OC基础--类
都是注释哈 类的组成: C语言中函数分为声明和实现 OC中定义一个类也分为声明和实现, 也就是说以后我们在OC中定义类, 就是在写类的声明和实现 编写类的声明和实现: 声明 .h: /* 行为方法: ...
- Qt之WebKit学习之绘图
void Serial::on_pushButton_clicked() { //scroll(4,0); flag_btn = true; // this->update(); //绘图绘在窗 ...
- sql整型字段模糊查询
select count(*) cnt from vhuiy where CAST(id as text) like'%12%'--id为int类型 更详细的链接:http://www.studyof ...
- warning C4305: “=”: 从“int”到“unsigned char”截断解决方法[zz]
在控制台程序中定义: float x; x=22.333; 编译会出现 warning C4305: “初始化”: 从“double”到“float”截断 系统默认此浮点数是22.333是double ...
- quartz.net 使用(一)-执行定时计划任务
一.使用nuget安装所需要的包 Install-Package Quartz 二.实现自己的job继承IJob public class FirstJob : IJob { public void ...
- 使用GnuRadio+OpenLTE+SDR搭建4G LTE基站(上)
0×00 前言 在移动互联网大规模发展的背景下,智能手机的普及和各种互联网应用的流行,致使对无线网络的需求呈几何级增长,导致移动运营商之间的竞争愈发激烈.但由于资费下调等各种因素影响,运营商从用户获得 ...
- C#—WebService
一.qq是否在线 1.添加Web引用 qqOnlineWebService cn.com.webxml.www.qqOnlineWebService shelly1 = new NIIT1109 ...
- sublime开发php必备工具集合(mac)
sublime开发php必备工具集合(Mac) 相关链接:http://benmatselby.github.io/sublime-phpcs/ 目标: 直接在sublime中运行php代码 按PSR ...