yield 关键字向编译器指示它所在的方法是迭代器块。编译器生成一个类来实现迭代器块中表示的行为。在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值。这是一个返回值,例如,在 foreach 语句的每一次循环中返回的值。yield 关键字也可与 break 结合使用,表示迭代结束。

例子:
yield return <expression>;
yield break;

在 yield return 语句中,将计算 expression 并将结果以值的形式返回给枚举器对象;expression 必须可以隐式转换为 yield 类型的迭代器。

在 yield break 语句中,控制权将无条件地返回给迭代器的调用方,该调用方为枚举器对象的 IEnumerator.MoveNext 方法(或其对应的泛型 System.Collections.Generic.IEnumerable<T>)或 Dispose 方法。

yield 语句只能出现在 iterator 块中,这种块可作为方法、运算符或访问器的主体实现。这类方法、运算符或访问器的体受以下约束的控制:

  • 不允许不安全块。

  • 方法、运算符或访问器的参数不能是 ref 或 out

  • yield return 语句不能放在 try-catch 块中的任何位置。该语句可放在后跟 finally 块的 try 块中。

  • yield break 语句可放在 try 块或 catch 块中,但不能放在 finally 块中。

yield 语句不能出现在匿名方法中。有关更多信息,请参见匿名方法(C# 编程指南)

当和 expression 一起使用时,yield return 语句不能出现在 catch 块中或含有一个或多个 catch 子句的 try 块中。

yield是C#为了简化遍历操作实现的语法糖,我们知道如果要要某个类型支持遍历就必须要实现系统接口IEnumerable,这个接口后续实现比较繁琐要写一大堆代码才能支持真正的遍历功能。举例说明

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.Linq;
  5. using System.Text;
  6.  
  7. namespace
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. HelloCollection helloCollection = new HelloCollection();
  14. foreach (string s in helloCollection)
  15. {
  16. Console.WriteLine(s);
  17. }
  18.  
  19. Console.ReadKey();
  20. }
  21. }
  22.  
  23. //public class HelloCollection : IEnumerable
  24. //{
  25. // public IEnumerator GetEnumerator()
  26. // {
  27. // yield return "Hello";
  28. // yield return "World";
  29. // }
  30. //}
  31.  
  32. public class HelloCollection : IEnumerable
  33. {
  34. public IEnumerator GetEnumerator()
  35. {
  36. Enumerator enumerator = new Enumerator();
  37. return enumerator;
  38. }
  39.  
  40. public class Enumerator : IEnumerator, IDisposable
  41. {
  42. private int state;
  43. private object current;
  44.  
  45. public Enumerator(int state)
  46. {
  47. this.state = state;
  48. }
  49.  
  50. public bool MoveNext()
  51. {
  52. switch (state)
  53. {
  54. case :
  55. current = "Hello";
  56. state = ;
  57. return true;
  58. case :
  59. current = "World";
  60. state = ;
  61. return true;
  62. case :
  63. break;
  64. }
  65. return false;
  66. }
  67.  
  68. public void Reset()
  69. {
  70. throw new NotSupportedException();
  71. }
  72.  
  73. public object Current
  74. {
  75. get { return current; }
  76. }
  77.  
  78. public void Dispose()
  79. {
  80. }
  81. }
  82. }
  83. }

上面注释的部分引用了"yield return”,其功能相当于下面所有代码!可以看到如果不适用yield需要些很多代码来支持遍历操作。

yield return 表示在迭代中下一个迭代时返回的数据,除此之外还有yield break, 其表示跳出迭代,为了理解二者的区别我们看下面的例子

  1. class A : IEnumerable
  2. {
  3. private int[] array = new int[];
  4.  
  5. public IEnumerator GetEnumerator()
  6. {
  7. for (int i = ; i < ; i++)
  8. {
  9. yield return array[i];
  10. }
  11. }
  12. }

如果你只想让用户访问ARRAY的前8个数据,则可做如下修改.这时将会用到yield break,修改函数如下

  1. public IEnumerator GetEnumerator()
  2. {
  3. for (int i = ; i < ; i++)
  4. {
  5. if (i < )
  6. {
  7. yield return array[i];
  8. }
  9. else
  10. {
  11. yield break;
  12. }
  13. }
  14. }

yield 关键字的更多相关文章

  1. 从yield关键字看IEnumerable和Collection的区别

    C#的yield关键字由来以久,如果我没有记错的话,应该是在C# 2.0中被引入的.相信大家此关键字的用法已经了然于胸,很多人也了解yield背后的“延迟赋值”机制.但是即使你知道这个机制,你也很容易 ...

  2. .NET中的yield关键字

    浅谈yield http://www.cnblogs.com/qlb5626267/archive/2009/05/08/1452517.html .NET中yield关键字的用法 http://bl ...

  3. 使用yield关键字让自定义集合实现foreach遍历

    一般来说当我们创建自定义集合的时候为了让其能支持foreach遍历,就只能让其实现IEnumerable接口(可能还要实现IEnumerator接口) 但是我们也可以通过使用yield关键字构建的迭代 ...

  4. C#的yield关键字

    using System; using System.Collections.Generic; using System.Reflection; using System.Text.RegularEx ...

  5. 从range和xrange的性能对比到yield关键字(中)

    上节提出了range和xrange的效率问题,这节我们来探究其中的原因   yield的使用   我们看下面的程序: #coding: utf-8 def test(): print 4 print ...

  6. (转) Python Generators(生成器)——yield关键字

    http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置.对生成器函数的第二次(或第 n 次) ...

  7. 转载yield关键字理解

    实现IEnumerable接口及理解yield关键字   [摘要]本文介绍实现IEnumerable接口及理解yield关键字,并讨论IEnumerable接口如何使得foreach语句可以使用. 本 ...

  8. yield关键字的用法

    在上一篇文章中,说了下foreach的用法,但是还是比较复杂的,要实现接口才能进行遍历,有没有简单些的方法呢?答案是肯定的.且看下面. yield关键字的用法: 1.为当前类型添加一个任意方法,但是要 ...

  9. yield 关键字和迭代器

    一般使用方法     yield 关键字向编译器指示它所在的方法是迭代器块 在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值. 这是一个返回值,例如,在 forea ...

  10. C# 基础小知识之yield 关键字 语法糖

    原文地址:http://www.cnblogs.com/santian/p/4389675.html 对于yield关键字我们首先看一下msdn的解释: 如果你在语句中使用 yield 关键字,则意味 ...

随机推荐

  1. nginx服务器的rewrite功能

    nginx编译的时候默认是把rewrite功能编辑进去的,但是因为rewrite需要使用正则表达式,因此需要安装pcre依赖包. yum install -y pcre pcre-install re ...

  2. 微信小程序——3、逻辑js文件

    逻辑层js文件 微信小程序前端进行了层次划分,分为逻辑层和视图层.逻辑层实现对数据的加工和处理.与HTML页面相似,逻辑层使用JavaScript编写.逻辑层将数据处理后发送至视图层,同时接受视图层的 ...

  3. C#对象的new和不new的区别

    new:为对象分配空间. 首先,直接声明一个变量:byte[] test;只是有了一个变量名字,而它是没有实际空间的,需要分配空间: 分配空间的方法: 1.使用new,byte[] test = ne ...

  4. Go第六篇之结构体剖析

    Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型.Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性. Go 语言中的类型可以被实例化,使用new或&a ...

  5. gensim工具[学习笔记]

    平台信息:PC:ubuntu18.04.i5.anaconda2.cuda9.0.cudnn7.0.5.tensorflow1.10.GTX1060 一.将copy_train.csv文件的内容进行分 ...

  6. win7 64位debug解决方法

    1.下载win 64位的DOSBox,如DOSBox0.74: 2.下载win 32 debug.exe,并复制到调用的目录,如d盘根目录d:\ 3.安装DOSBox,并运行:如下图: 4.键入命令: ...

  7. vim的加密和解密?

    vim中出现的错误提示含义: 参考: http://blog.csdn.net/u014599371/article/details/43955169 E488: trailing character ...

  8. 可持久化fhq-treap学习笔记

    目录 可持久化fhq-treap----- 支持查询历史版本的非旋treap 先看看为啥他可以可持久化 过程 别的 注意&&出错&&吐槽 模板->luoguP38 ...

  9. 51nod 1284 2 3 5 7的倍数

    从1到N 里 是2的倍数 有 N/2 个 然后大概看过这类的blog  所以运用容斥原理 直接计算 是 2 3 5 7 的个数都是多少 然后用N 减去 就是 不是2 3 5 7 的个数了 (离散好像也 ...

  10. 网络压缩论文整理(network compression)

    1. Parameter pruning and sharing 1.1 Quantization and Binarization Compressing deep convolutional ne ...