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函数就变成了一个生成器,当每次调用的时候,就会自 ...
随机推荐
- PHP 数组
// 这里用数字来作为索引 $myArray = array(2012, 'blue', 5, 'BMW'); // 这个用关键字作为索引 $myAssocArray = array('year' = ...
- new对象时,类名后加括号与不加括号的区别
[1]默认构造函数 关于默认构造函数,请参见随笔<类中函数> 请看测试代码: 1 #include <iostream> 2 using namespace std; 3 4 ...
- 【转载】VMware虚拟机修改硬盘容量大小
很多人在安装虚拟机系统的时候,为了节省硬盘空间,把硬盘容量设置得较小,可是后来发现硬盘容量不够用了.在VMware中又不能直接修改虚拟机的硬盘容量大小,或者重建虚拟机系统,非常麻烦. 其实在VMwar ...
- [HB2014 Week5] Allot 人员分配
这两天决心专门搞好网络流了 - - 题解在什么瞎胡搞跟我说要连n+2和n+1容量为无穷的边…我看了下std才做的… 坑死人的地方就是,需要求多次网络流,每次别忘了把流给清空了…这次是用链表所以专门写了 ...
- (转)oracle 存储过程 带游标作为OUT参数输出
(转)oracle 存储过程 带游标作为OUT参数输出 存储过程返回OUT参数的游标 例子. 包中带过程 要自己定义一个type [cur_name] is ref cursor游标,返回的时候就直接 ...
- SharePoint 2016 开发 工具Preview发布
博客地址:http://blog.csdn.net/FoxDave 之前装了SharePoint,但是并不能在Visual Studio 2015里面做开发,因为没有相应的office tool. 但 ...
- GFT_News Auto
using AnfleCrawler.Common; using Newtonsoft.Json.Linq; using System; using System.Collections.Generi ...
- Graphic geometry
Graphic有3个很重要的属性:geometry.symbol和attributes. •geometry属性定义的是一个几何对象,它是Graphic的基础,因为Graphic要表达的就是这个几何对 ...
- char*或string转换成LPCWSTR
VS2010默认是Unicode的,在VC 6.0中编译成功的项目在VS2010中常会出现类型错误. 经常出现的错误是:不能从const char *转换为LPCWSTR 如使用CreateDC(&q ...
- Ubuntu安装gfortran
命令行运行 sudo apt-get install gfortran