C#中的yield return与Unity中的Coroutine(协程)(上)
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(协程)(上)的更多相关文章
- C#中的yield return与Unity中的Coroutine(协程)(下)
Unity中的Coroutine(协程) 估计熟悉Unity的人看过或者用过StartCoroutine() 假设我们在场景中有一个UGUI组件, Image: 将以下代码绑定到Image using ...
- 可惜Java中没有yield return
项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...
- C#中的yield return用法演示源码
下边代码段是关于C#中的yield return用法演示的代码. using System;using System.Collections;using System.Collections.Gene ...
- Unity之"诡异"的协程
为什么说是诡异的协程呢?首先从一个案例说起吧,示例如下: 游戏目标:让小车进入到对应颜色屋子里,即可获得一分.(转弯的道路可控) 为了让小车能够平滑转弯,小车的前进方向需要和车子的位置与圆心组成的 ...
- C#中的yield return
4.1 迭代器块 一个迭代器块(iterator block)是一个能够产生有序的值序列的块.迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句. yield return语句产生迭代的 ...
- Android中的Coroutine协程原理详解
前言 协程是一个并发方案.也是一种思想. 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高.但是面对计算密集型的任务不如多线程并行运算效率高. 不同的语言对于协程都有不同的实 ...
- Unity脚本编程之——协程(Coroutine)
本文翻译自Unity官方文档:https://docs.unity3d.com/Manual/Coroutines.html 专有名词: Coroutine 协程 Alpha 不透明度 当你调用一个函 ...
- 【Unity笔记】使用协程(Coroutine)异步加载场景
using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; using System; public ...
- Unity带参数的协程
两种方法都可以传递参数,代码如下: using UnityEngine; using System.Collections; public class Test : MonoBehaviour { v ...
随机推荐
- inux下文件权限设置中的数字表示权限,比如777,677等,这个根据什么得来的
chmod ABC file 其中A.B.C各为一个数字,分别表示User.Group.及Other的权限. A.B.C这三个数字如果各自转换成由“0”.“1”组成的二进制数,则二进制数的每一位分别代 ...
- python datetime模块用strftime 格式化时间
1 2 3 #!usr/bin/python import datetime datetime.datetime.now() 这个会返回 microsecond.因此这个是我们不需要的.所以得做一下修 ...
- 使用nmon监控服务器性能
1.下载nmon:http://nmon.sourceforge.net/pmwiki.php?n=Site.Download 2.选择适合Linux系统版本的相应nmon版本,Linux查看系统版本 ...
- 【Android Demo】获取指定网页的页面源代码
1.直接上效果图 2.代码 主要就是工具类HtmlService.java: import java.io.ByteArrayOutputStream; import java.io.InputStr ...
- 2014 Super Training #6 G Trim the Nails --状态压缩+BFS
原题: ZOJ 3675 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3675 由m<=20可知,可用一个二进制数表 ...
- POJ 3255 Roadblocks --次短路径
由于次短路一定存在,则可知次短路一定是最短路中某一条边不走,然后回到最短路,而且只是一条边,两条边以上不走的话,就一定不会是次短路了(即以边换边才能使最小).所以可以枚举每一条边,算出从起点到这条边起 ...
- HDU 1556 Color the ball
这题用线段树的话简直就是一个水题..不过刚学树状数组,要用一下. 题意:每次给你a,b,表明a~b之间涂色,然后最后一次输出每个气球被涂色的次数. 要用树状数组就要考虑怎么转化为前缀和问题,这题可以这 ...
- CSU 1116 Kingdoms
题意:给你n个城市,m条被摧毁的道路,每条道路修复需要c元,总共有k元,给你每个城市的人口,问在总费用不超过k的情况下 与1号城市相连的城市的最大总人口(包括1号城市) 思路:1号城市是必取的,剩余最 ...
- 第2章 面向对象的设计原则(SOLID):2_里氏替换原则(LSP)
2. 里氏替换原则(Liskov Substitution Principle,LSP) 2.1 定义 (1)所有使用基类的地方必须能透明地使用子类替换,而程序的行为没有任何变化(不会产生运行结果错误 ...
- 转 异常处理汇总 ~ 修正果带着你的Net飞奔吧!
异常处理汇总 ~ 修正果带着你的Net飞奔吧! 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 异常处理汇总-开发工具 h ...