原文:C# yield return 用法与解析

C# yield return 用法与解析

本文参考自:http://www.jb51.net/article/54810.htm

当初没有认真理解 yield 这个关键字,现在又遇到了依旧不理解,为了以后不再为了 yield 困惑,决定好好研究一下 yield 的用法与意义:

yield 从字面上理解有“退位,屈服”的意思,转一下弯就理解成“权限转移”,也就是将控制权交给别人,在这里就是把集合里满足条件(如果没有过滤条件,就是全体)的个体的操作转移给另一个对象。

    class Program
{
static void Main(string[] args)
{
foreach (var item in FilterWithoutYield)
{
Console.WriteLine(item);
}
Console.ReadKey();
} //申明属性,定义数据来源
public static List<int> Data
{
get
{
return new List<int>(){,,,,,,,};
}
} //申明属性,过滤器(不适用yield)
public static IEnumerable<int> FilterWithoutYield
{
get
{
var result = new List<int>();
foreach (var i in Data)
{
if (i > )
result.Add(i);
}
return result;
}
}
}

可以看到如果不用yield,要返回大于4的所有的树,就要到另一个集合。而用yield的情况下就不必如此麻烦了:

        //申明属性,过滤器(使用yield)
public static IEnumerable<int> FilterWithoutYield
{
get
{
foreach (var i in Data)
{
if (i > )
yield return i;
}
}
}

为什么会这样呢?

通过单步调试发现:

虽然2种方法的输出结果是一样的,但运作过程迥然不同。第一种方法,是把结果集全部加载到内存中再遍历;第二种方法,客户端每调用一次,yield return就返回一个值给客户端,是"按需供给"。

第一种方法,客户端调用过程大致为:

使用yield return,客户端调用过程大致为:

使用yield return为什么能保证每次循环遍历的时候从前一次停止的地方开始执行呢?

--因为,编译器会生成一个状态机来维护迭代器的状态。

简单地说,当希望获取一个IEnumerable<T>类型的集合,而不想把数据一次性加载到内存,就可以考虑使用yield return实现"按需供给"。

C# yield return 用法与解析的更多相关文章

  1. yield关键字用法与解析(C# 参考)

    yield 关键字向编译器指示它所在的方法是迭代器块. 编译器生成一个类来实现迭代器块中表示的行为. 在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值. 这是一个返 ...

  2. C#中yield return用法分析

    这篇文章主要介绍了C#中yield return用法,对比使用yield return与不使用yield return的流程,更直观的分析了yield return的用法,需要的朋友可以参考下. 本文 ...

  3. C# yield return用法

    本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解.具体如下: yield关键字用于遍历循环中,yi ...

  4. C#中的yield return用法演示源码

    下边代码段是关于C#中的yield return用法演示的代码. using System;using System.Collections;using System.Collections.Gene ...

  5. C#中yield return用法

    转载:http://www.jb51.net/article/54810.htm http://www.cnblogs.com/HunterWei/archive/2012/06/13/csharpy ...

  6. yield return的用法简介

    使用yield return 语句可一次返回一个元素. 迭代器的声明必须满足以下要求: 返回类型必须为 IEnumerable.IEnumerable<T>.IEnumerator 或 I ...

  7. 关于迭代器及yield的用法

    1.foreach语句 C#编译器会把foreach语句转换为IEnumerable接口的方法和属性. foreach (Person p in persons) { Console.WriteLin ...

  8. List<T>集合的Sort自定义排序用法简单解析

    List<T>集合的Sort自定义排序用法简单解析: 如下:一系列无序数字,如果想要他们倒序排列,则使用如下代码: 那么如何理解这段代码呢? (x,y)表示相邻的两个对象,如果满足条件:x ...

  9. 【Unity】协程Coroutine及Yield常见用法

    最近学习协程Coroutine,参考了别人的文章和视频教程,感觉协程用法还是相当灵活巧妙的,在此简单总结,方便自己以后回顾.Yield关键字的语意可以理解为“暂停”. 首先是yield return的 ...

随机推荐

  1. Android开发实例-健康食谱应用(一)

    转载请注明出处:http://blog.csdn.net/einarzhang/article/details/44774635 本系列文章的重点是如何使用Android开发一个简单的健康食谱软件.使 ...

  2. JS浮点类型计算

    /* ---------------- JS浮点数运算重置 ---------------- */ //加法函数 //调用:accAdd(arg1,arg2) //返回值:arg1加上arg2的精确结 ...

  3. linux的文件系统及节点表

    linux的文件系统及节点表 一  linux的文件系统1 我们都知道当我们安装linux时会首先给系统分区,然后我们会把分区格式化成EXT3格式的文件系统.那么在linux系统中还有没有其他的文件系 ...

  4. Qt 学习之路:线程和 QObject

    前面两个章节我们从事件循环和线程类库两个角度阐述有关线程的问题.本章我们将深入线程间得交互,探讨线程和QObject之间的关系.在某种程度上,这才是多线程编程真正需要注意的问题. 现在我们已经讨论过事 ...

  5. app 的内存优化

    这篇文章是笔者在开发App过程中发现的一些内存问题, 然后学习了YYKit框架时候也发现了图片的缓存处理 (YYKit 作者联系了我, 说明了YYKit重写imageNamed:的目的不是为了内存管理 ...

  6. 编写android的widget

    以前对这个东西很感兴趣,因为确实方便,如今有时间了来做一个例子 首先要定义一个layout(widgetview.xml)和一个配置文件(widgetconfig.xml) <?xml vers ...

  7. 用户输出表单处理php

    php中的表单输入处理,我用两个文件,在linux输出: touch php_post1.html php_post1.php php_post1.html代码如下: <!doctype htm ...

  8. table转list

    DataTable数据集转换为List非泛型以及泛型方式 前言 DataTable是断开式的数据集合,所以一旦从数据库获取,就会在内存中创建一个数据的副本,以便使用.由于在实际项目中,经常会将 Dat ...

  9. 菜鸟学开店—自带U盘的打印机

    本文旨在提供最简单.便宜.有效的解决方案,解决普通用户最困扰的问题.今天提供普通用户一个低价的小票打印机驱动安装解决方案 相信很多用户都碰到过这种情况,电脑的重装了系统,打印机的驱动没有备份,要用打印 ...

  10. Sprite Kit教程:初学者

    作者:Ray Wenderlich 原文出处:点击打开链接 http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 转自 ...