C# 迭代器与 Unity协程

迭代器

迭代器: 用于遍历可迭代集合的工具,下一个元素的引用由上一个迭代而来。

如果对象需要能被 foreach 迭代遍历或对外提供迭代器用于遍历,则需实现 IEnumerable 接口。

传统写法:

using System;
using System.Collections.Generic;
using System.Collections;

class A : IEnumerable
{
    List<int> list;

	//对外提供迭代该类对象的迭代器
    public IEnumerator GetEnumerator()
    {
    	//直接返回需要被迭代遍历的对象的迭代器或自定义迭代器
        //return list.GetEnumerator();
        return new AEnumerator() { list = this.list};
    }
}

class AEnumerator : IEnumerator
{
    public object Current { get => list[index]; }

    public List<int> list;
    public int index = -1;

    public bool MoveNext()
    {
        index++;
        return index < list.Count;
    }

    public void Reset()
    {
        index = -1;
    }
}

使用

	A a = new A();
	IEnumerator iterator = a.GetEnumerator();
    while (iterator.MoveNext())
    {
        Console.WriteLine(iterator.Current);
    }
    //或者使用foreach
    foreach(var item in a){
    	Console.WriteLine(item);
	}

yield return写法:

class A : IEnumerable
{
    List<int> list;

    public IEnumerator GetEnumerator()
    {
        for(int i = 0; i < list.Count; ++i)
        {
            yield return list[i];
        }
    }
}

这样写代码简洁了不少,但外部的迭代调用方式是不变的。

yield return的原理: 每次调用 MoveNext(),都会执行一段代码,直到遇到 yield return 退出,yield return 的结果作为 Current 的值。下一次调用 MoveNext(),从上一次 yield return 的地方继续往下执行。

协程

	中断: yield break;
	yield return
	-- WaitForFixedUpdate //在FixedUpdate后执行
		
	-- null0...//在每帧Update之后执行

	--WaitForEndOfFrame //在每帧结束后执行

	--WWW //在请求结束后执行

	--WaitForSeconds //在几秒后再调用

Start也可写作协程
会被 Unity 在 Start 时自动调用,按照普通协程执行。

	private IEnumerator Start(){
		yield return xxx;
	}

协程的开启

1.StartCoroutine(Fun(arg));
优点:
性能开销小,支持多参数调用;
缺点:
无法单独停止该协程
StopCoroutine(Fun(arg)) 是无法停止该类协程的

2.StartCoroutine(string methodName, object value = null);
缺点:最多一个参数,且性能开销大

嵌套协程

	private IEnumerator Fun1(){
		yield return StartCoroutine(Fun2());
		print("xx"); //会等到fun2协程执行完毕
	}
	private IEnumerator Fun2(){
		yield return new WaitForSeconds(2);
	}

协程的停止

StopCoroutine(string):只能停止以字符串为参开启的协程
StopAllCoroutine():停止开启的所有协程

协程应用

将耗时操作写在随时间进行的协程中处理
将需分步处理的内容通过一次 StartCoroutine 处理

注意事项
  • 可以定义静态协程
  • IEnumerator类型的方法不能带ref或者out型的参数
  • 协程是依赖 GameObject 的,而不是脚本,所以协程开启后禁用脚本并不能停止协程,禁用 gameObject 才能
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值