共计 3082 个字符,预计需要花费 8 分钟才能阅读完成。
导读 | 本文详细讲解了 C# 中的 yield 关键字,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 |
在 ”C# 中, 什么时候用 yield return” 中,我们了解到:使用 yield return 返回集合,不是一次性加载到内存中,而是客户端每调用一次就返回一个集合元素,是一种 ” 按需供给 ”。本篇来重温 yield return 的用法,探秘 yield 背后的故事并自定义一个能达到 yield return 相同效果的类,最后体验 yield break 的用法。
以下代码创建一个集合并遍历集合。
class Program | |
{static Random r = new Random(); | |
static IEnumerable GetList(int count) | |
{List list = new List(); | |
for (int i = 0; i |
使用 yield return 也能获得同样的结果。修改 GetList 方法为:
static IEnumerable GetList(int count) | |
{for (int i = 0; i |
通过断点调试发现:客户端每显示一个集合中的元素,都会到 GetList 方法去获取集合元素。
使用 yield return 获取集合,并遍历。
class Program | |
{public static Random r = new Random(); | |
static IEnumerable GetList(int count) | |
{for (int i = 0; i |
生成项目,并用 Reflector 反编译可执行文件。在.NET 1.0 版本下查看 GetList 方法,发现该方法返回的是一个 GetList 类的实例。原来 yield return 是 ” 语法糖 ”,其本质是生成了一个 GetList 的实例。
那 GetList 实例是什么呢?点击 Reflector 中
接下来,就模拟 GetList,我们自定义一个 GetRandomNumbersClass 类,使之能达到 yield return 相同的效果。
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
namespace ConsoleApplication2 | |
{ | |
class Program | |
{public static Random r = new Random(); | |
static IEnumerable GetList(int count) | |
{GetRandomNumbersClass ret = new GetRandomNumbersClass(); | |
ret.count = count; | |
return ret; | |
} | |
static void Main(string[] args) | |
{foreach(int item in GetList(5)) | |
Console.WriteLine(item); | |
Console.ReadKey();} | |
} | |
class GetRandomNumbersClass : IEnumerable, IEnumerator | |
{ | |
public int count;// 集合元素的数量 | |
public int i; // 当前指针 | |
private int current;// 存储当前值 | |
private int state;// 保存遍历的状态 | |
public int Current | |
{get { return current;} | |
} | |
public bool MoveNext() | |
{switch (state) | |
{ | |
case 0: // 即为初始默认值 | |
i = 0;// 把指针调向 0 | |
goto case 1; | |
break; | |
case 1: | |
state = 1;// 先设置原状态 | |
if (!(i GetEnumerator() | |
{return this;} | |
// 被显式调用的属性 | |
IEnumerator IEnumerable.GetEnumerator() | |
{return GetEnumerator(); | |
} | |
} | |
} |
关于 GetRandomNumbersClass 类:
迭代器的 MoveNext 方法是关键:
如此循环
假设在一个无限循环的环境中获取一个 int 类型的集合,在客户端通过某个条件来终止循环。
class Program | |
{static Random rand = new Random(); | |
static IEnumerable GetList() | |
{while (true) | |
{yield return rand.Next(100); | |
} | |
} | |
static void Main(string[] args) | |
{foreach (int item in GetList()) | |
{if (item%10 == 0) | |
{break;} | |
Console.WriteLine(item); | |
} | |
Console.ReadKey();} | |
} |
以上,当集合元素可以被 10 整除的时候,就终止循环。终止循环的时机是在循环遍历的时候。
如果用 yield break, 就可以在获取集合的时候,当符合某种条件就终止获取集合。
class Program | |
{static Random rand = new Random(); | |
static IEnumerable GetList() | |
{while (true) | |
{int temp = rand.Next(100); | |
if (temp%10 == 0) | |
{yield break;} | |
yield return temp; | |
} | |
} | |
static void Main(string[] args) | |
{foreach (int item in GetList()) | |
{Console.WriteLine(item); | |
} | |
Console.ReadKey();} | |
} |
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值
