C# yield
C#中的yield可以应用在一个可迭代的方法中,我们必须真正理解此关键词,才能将它正确的应用到实际生产中。为了说明yield会出现让我们迷惑的结果,下面先定义一个MyObject类:
class MyObject
{
public int Value{get;set;}
}
MyObject类用于存放一个值,下面定义一个IEnumerable<MyObject>的方法:
IEnumerable<MyObject> GetYieldObjects()
{
for (int i = ; i < ; i++)
{
Console.WriteLine("GetObjects() i="+i.ToString());
yield return new MyObject() { Value = i };
}
}
方法中用yield return返回实例化的MyObject对象,为了便于记录GetYieldObjects()方法实际调用的过程,这里用Console.WriteLine来记录每次调用的过程。下面声明一个objects对象,然后进行第一次迭代,在第一次迭代过程中,对每个迭代项目的值进行+10处理,然后进行第2此迭代,看看是否会将处理后的值进行输出:
//此时不调用GetObjects()的内部循环
var objects = GetYieldObjects();
//每次迭代会调用GetObjects()对应i的内容
foreach (var item in objects)
{
Console.WriteLine("1 foreach (var item in objects) item.Value=" + item.Value.ToString());//0..9
item.Value += ;
}
//每次迭代会调用GetObjects()对应i的内容
foreach (var item in objects)
{
Console.WriteLine("2 foreach (var item in objects) item.Value=" + item.Value.ToString());//0..9
Console.WriteLine(item.Value.ToString());//0..9
}
在第2次迭代时,输出的还是0到9,并不是10到19.请看下面的迭代过程:
当第一次迭代时候,每次迭代会调用GetObject()方法中的yield return语句,而不是在var objects=GetObjects()进行实例化。当yield取到一个MyObject对象后立刻返回给迭代器,并将其值进行输出,然后继续调用GetObjects方法中的yield return语句,
因此每次循环时,实际上都是一个新的对象。如下图所示:


当然如果将上面的代码稍作修改,用objects=GetYieldObjects().ToArray()的话,那么第二次输出的就是10到19:
objects = GetYieldObjects().ToArray();
foreach (var item in objects)
{
item.Value += ;
} foreach (var item in objects)
{
Console.WriteLine(item.Value.ToString());//10..19
}
C# yield的更多相关文章
- Python 生成器与迭代器 yield 案例分析
前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...
- node 异步回调解决方法之yield
先看如何使用 使用的npm包为genny,npm 安装genny,使用 node -harmony 文件(-harmony 为使用es6属性启动参数) 启动项目 var genny= require( ...
- yield生成器及字符串的格式化
一.生成器 def ran(): print('Hello world') yield 'F1' print('Hey there!') yield 'F2' print('goodbye') yie ...
- Python中的生成器与yield
对于python中的yield有些疑惑,然后在StackOverflow上看到了一篇回答,所以搬运过来了,英文好的直接看原文吧. 可迭代对象 当你创建一个列表的时候,你可以一个接一个地读取其中的项.一 ...
- Python yield函数理解
Python中的yield函数的作用就相当于一个挂起,是不被写入内存的,相当于一个挂起的状态,用的时候迭代,不用的时候就是一个挂起状态,挂起状态会以生成器的状态表现
- ecma6 yield
function * generator(k){ console.log('begin'); var x = yield k; console.log('x:',x); var y = yield x ...
- Python yield与实现
Python yield与实现 yield的功能类似于return,但是不同之处在于它返回的是生成器. 生成器 生成器是通过一个或多个yield表达式构成的函数,每一个生成器都是一个迭代器(但是迭 ...
- 可惜Java中没有yield return
项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...
- 使用yield进行异步流程控制
现状 目前我们对异步回调的解决方案有这么几种:回调,deferred/promise和事件触发.回调的方式自不必说,需要硬编码调用,而且有可能会出现复杂的嵌套关系,造成"回调黑洞" ...
- GetEnumerator();yield
GetEnumerator()方法的实质实现: 说明:只要一个集合点出GetEnumerator方法,就获得了迭代器属性,就可以用MoveNext和Current来实现foreach的效果,如上图. ...
随机推荐
- iOS越狱开发(一)
做越狱开发也有一些时间了,有很多东西想总结一下,希望给他人一些借鉴,也是自己对过去开发经历的一些总结.个人不推荐使用盗版,这里主要以技术介绍为主. 这个系列里面主要介绍怎样进行越狱开发,涉及到以下几个 ...
- WEBAPP开发技巧(手机网站开发注意事项)
以下只是我个人得总结,如果你有更好的建议,请留言,一起共勉进步!!- -! 1.要响应式开发web,也就是页面必须自适应屏幕大小,可以采用流体布局,如之前的文章(自适应宽度布局),其他具体的小问题可以 ...
- ES6入门系列四(测试题分析)
0.导言 ES6中新增了不少的新特性,来点测试题热热身.具体题目来源请看:http://perfectionkills.com/javascript-quiz-es6/. 以下将一题一题来解析what ...
- 算法设计和数据结构学习_5(BST&AVL&红黑树简单介绍)
前言: 节主要是给出BST,AVL和红黑树的C++代码,方便自己以后的查阅,其代码依旧是data structures and algorithm analysis in c++ (second ed ...
- Tools - Markdown
Markdown 轻量级标记语言,使用易读易写的纯文本格式和类似HTML的标记语法来编写具有一定的格式的文档. wiki - Markdown 三分钟学会书写格式良好的笔记(Markdown) 为知笔 ...
- JVM的GC概述
JVM的GC概述 GC即垃圾回收,是指jvm用于释放那些不再使用的对象所占用的内存.在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能. 有些垃圾收集专用于特殊的应用程序.比如,实时应用程序 ...
- Azure ARM (6) ARM Template简单介绍
<Windows Azure Platform 系列文章目录> Azure ARM (1) 概览 Azure ARM (2) 概览 Azure ARM (3) ...
- redis学习教程之一基本命令
参阅redis中文的 互动教程(interactive tutorial)来学习的. 目录: 全局操作 get get incr 自增 del 删除 expire 定时 list 队列 set ...
- [Java 进阶]异常
异常:程序在运行过程中发生由于硬件设备问题.软件设计错误等导致的程序异常事件. 世上没有百分之百完美的程序.程序总难免存在各式各样的问题.所以,程序中添加对于错误的处理机制是十分有必要的.这就好比人多 ...
- SQL Server安全(7/11):使用跨数据库所有权链接(Cross-Database Ownership Chaining)的跨数据库安全
在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...