C#中的yield return

C#语法中有个特别的关键字yield, 它是干什么用的呢?

来看看专业的解释:

yield 是在迭代器块中用于向枚举数对象提供值或发出迭代结束信号。它的形式为下列之一:
yield return <expression>;
yield break

看如下例子:

       public class CustomCollection :IEnumerable {

           public static void Main (string[] args)
{
CustomCollection cc = new CustomCollection (); foreach (String word in cc) {
Console.WriteLine ("word:" +word);
}
} public IEnumerator GetEnumerator(){ yield return "Hello";
yield return "Boys";
yield return "And";
yield return "Girls";
//return new HelloBoyGirls(); }
} // public class HelloBoyGirls: IEnumerator {
// private int cusor = -1;
// private String[] words = {"Hello", "Boys", "And", "Girls"};
//
// public bool MoveNext ()
// {
// cusor++;
// return cusor < words.Length;
// }
//
// public void Reset ()
// {
// cusor = 0;
// }
//
// public object Current {
// get {
// return words [cusor];
// }
// }
// }

上面的例子是实现了一个自定义的迭代器;实现可迭代(可以用foreach)的数据集合,必须实现GetEmumerator()方法,返回实现了IEmumerator的对象实例。

完成这个, 有两种方法,一种是用上面注释掉的代码,一种是用yield return. yield return 需要配合IEmumerator进行使用, 在外部foreach循环中,它会执行GetEmumerator()方法,遇到yield return, 做了如下两件事情:

1.记录下当前执行到的代码位置

2. 将代码控制权返回到外部, yield return 后面的值, 作为迭代的当前值。

当执行下一个循环, 从刚才记录的代码位置后面, 开始继续执行代码。

简单地说, yield return 就是实现IEmumerator的超级简化版, 是不是很简单?

那么问题又来了, yield return 是如何决定循环该结束,yield return 之后的代码, 什么时候执行呢?

把上面的例子改造一下, 不要用方便的foreach了, 用while 循环自己控制:

     public class CustomCollection :IEnumerable {

         public static void Main (string[] args)
{
CustomCollection cc = new CustomCollection (); IEnumerator enumerator = cc.GetEnumerator ();
while (true) {
bool canMoveNext = enumerator.MoveNext ();
Console.WriteLine ("canMoveNext:" +canMoveNext);
if (!canMoveNext)
break;
Object obj = enumerator.Current;
Console.WriteLine ("current obj:" +obj);
}
// foreach (String word in cc) {
// Console.WriteLine ("word:" +word);
// }
Console.WriteLine ("Main End."); } public IEnumerator GetEnumerator(){ yield return "Hello";
yield return "Boys";
yield return "And";
yield return "Girls"; Console.WriteLine ("After all yield returns.");
//return new HelloBoyGirls(); }
}

运行代码, 结果是:

canMoveNext:True
current obj:Hello
canMoveNext:True
current obj:Boys
canMoveNext:True
current obj:And
canMoveNext:True
current obj:Girls
After all yield returns.
canMoveNext:False
Main End.

说明, 在GetEmumerator()中, 只有yield return 语句, 外部调用MoveNext()都为true, current就是yield return后面的对象

除了yield return, 还有yield break; yield break 的作用是, 停止循环, MoveNext()为false, yield break 之后的语句, 不会被执行!

有兴趣的童鞋, 可以自己写个例子试试。

C#中的yield return与Unity中的Coroutine(协程)(上)的更多相关文章

  1. C#中的yield return与Unity中的Coroutine(协程)(下)

    Unity中的Coroutine(协程) 估计熟悉Unity的人看过或者用过StartCoroutine() 假设我们在场景中有一个UGUI组件, Image: 将以下代码绑定到Image using ...

  2. 可惜Java中没有yield return

    项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...

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

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

  4. Unity之"诡异"的协程

    为什么说是诡异的协程呢?首先从一个案例说起吧,示例如下: 游戏目标:让小车进入到对应颜色屋子里,即可获得一分.(转弯的道路可控)   为了让小车能够平滑转弯,小车的前进方向需要和车子的位置与圆心组成的 ...

  5. C#中的yield return

    4.1 迭代器块 一个迭代器块(iterator block)是一个能够产生有序的值序列的块.迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句. yield return语句产生迭代的 ...

  6. Android中的Coroutine协程原理详解

    前言 协程是一个并发方案.也是一种思想. 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高.但是面对计算密集型的任务不如多线程并行运算效率高. 不同的语言对于协程都有不同的实 ...

  7. Unity脚本编程之——协程(Coroutine)

    本文翻译自Unity官方文档:https://docs.unity3d.com/Manual/Coroutines.html 专有名词: Coroutine 协程 Alpha 不透明度 当你调用一个函 ...

  8. 【Unity笔记】使用协程(Coroutine)异步加载场景

    using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; using System; public ...

  9. Unity带参数的协程

    两种方法都可以传递参数,代码如下: using UnityEngine; using System.Collections; public class Test : MonoBehaviour { v ...

随机推荐

  1. 运行编译后的程序报错 error while loading shared libraries: lib*.so: cannot open shared object file: No such file or directory

    运行编译后的程序报错  error while loading shared libraries: lib*.so: cannot open shared object file: No such f ...

  2. C++STL之迭代器2

    在学习c++ STL的时候,整天碰到迭代器,也整天用,但是,到底它是个什么东西,很多人没有一个认识.这里我通过几个小的DEMO,来看看迭代器.首先我实现了一个十分简陋的vector类: templat ...

  3. Sample SecondarySort 浅析

    示例文件: 100 99 100 98 100 56 100 78 20 100 30 100 20 50 30 50 30 60 20 80 需求:首先按第一个数字分组,组成按第二个数字排序. 解决 ...

  4. [转]ionic项目之上传下载数据

    本文转自:http://blog.csdn.net/superjunjin/article/details/44158567 一,首先是上传数据 记得在angularjs的controller中注入$ ...

  5. 【C#】C# 实现发送手机短信

    现在很多网站都是短信发送的功能,怎么实现的呢.对于个人站长来说的话,通过使用SMS短信通API接口相对比较划算和简单.那怎么实现呢,步骤如下: 1. 从网上(http://sms.webchinese ...

  6. 【温故而知新-Javascript】图片效果(图像震动效果、闪烁效果、自动切换图像)

    1.当鼠标指针经过图像时图像震动效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  7. IIS关于“ 配置错误 不能在此路径中使用此配置节”的解决办法

    IIS关于“ 配置错误 不能在此路径中使用此配置节”的解决办法 原文链接:http://www.cnblogs.com/200325074/p/3679316.html 今天刚安装好IIS8.5, 我 ...

  8. mac os利用xampp实现apache下的cgi

    折腾了两天终于把问题解决了,mac os是10.10.3..够新了吧 系统原生的apache配置cgi老是配不好,突然发现xampp也有macos版的,准备下下来试试. 安装完成后,打开apache服 ...

  9. 2014 Super Training #1 F Passage 概率DP

    原题: HDU 3366   http://acm.hdu.edu.cn/showproblem.php?pid=3366 本来用贪心去做,怎么都WA,后来看网上原来是一个DP题. 首先按P/Q来做排 ...

  10. Topcoder SRM 619 DIv2 500 --又是耻辱的一题

    这题明明是一个简单的类似约瑟夫环的问题,但是由于细节问题迟迟不能得到正确结果,结果比赛完几分钟才改对..耻辱. 代码: #include <iostream> #include <c ...