C# 中的"yield"使用

1.简化遍历操作实现的语法糖

我们知道如果要要某个类型支持遍历就必须要实现系统接口IEnumerable,这个接口后续实现比较繁琐要写一大堆代码才能支持真正的遍历功能。举例说明:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloCollection helloCollection = new HelloCollection();
            foreach (string s in helloCollection)
            {
                Console.WriteLine(s);
            }

            Console.ReadKey();
        }
    }
    //注释的代码其功能相当于下面所有代码!
    //public class HelloCollection : IEnumerable
    //{
    //    public IEnumerator GetEnumerator()
    //    {
    //        yield return "Hello";
    //        yield return "World";
    //    }
    //}

    public class HelloCollection : IEnumerable
    {
        public IEnumerator GetEnumerator()
        {
            Enumerator enumerator = new Enumerator(0);
            return enumerator;
        }

        public class Enumerator : IEnumerator, IDisposable
        {
            private int state;
            private object current;

            public Enumerator(int state)
            {
                this.state = state;
            }

            public bool MoveNext()
            {
                switch (state)
                {
                    case 0:
                        current = "Hello";
                        state = 1;
                        return true;
                    case 1:
                        current = "World";
                        state = 2;
                        return true;
                    case 2:
                        break;
                }
                return false;
            }

            public void Reset()
            {
                throw new NotSupportedException();
            }

            public object Current
            {
                get { return current; }
            }

            public void Dispose()
            {
            }
        }
    }
}

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

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

class A : IEnumerable
{
    private int[] array = new int[10];

    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < 10; i++)
        {
            yield return array[i];
        }
    }
}

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

public IEnumerator GetEnumerator()
{
    for (int i = 0; i < 10; i++)
    {
        if (i < 8)
        {
            yield return array[i];
        }
        else
        {
            yield break;
        }
    }
}

 这样,则只会返回前8个数据.

转自:https://www.cnblogs.com/kingcat/archive/2012/07/11/2585943.html

2.协程

协程:协同程序,在主程序运行的同时,开启另外一段逻辑处理,来协同当前程序的执行,。

2.1开启协程的两种方式

2.1.1、StartCoroutine(string methodName)

注意:

(1)、参数是方法名(字符串类型),此方法可以包含一个参数

(2)、形参方法可以有返回值

 

2.1.2、StartCoroutine(IEnumerator method)

注意:

(1)、参数是方法名(TestMethod()),方法中可以包含多个参数

(2)、IEnumrator 类型的方法不能含有ref或者out 类型的参数,但可以含有被传递的引用

(3)、必须有有返回值,且返回值类型为IEnumrator,返回值使用(yield retuen +表达式或者值,或者 yield break)语句

2.2终止协程的两种方式:

2.2.1StopCoroutine (string methodName):只能终止指定的协程

使用时注意:

在程序中调用StopCoroutine() 方法只能终止以字符串形式启动的协程

 

2.2.2StopAllCoroutine():终止所有协程

2.3yield:挂起,程序遇到yield关键字时会被挂起,暂停执行,等待条件满足时从当前位置继续执行

yield return 0 or yield return null:程序在下一帧中从当前位置继续执行

yield return 1,2,3,......:程序等待1,2,3...帧之后从当前位置继续执行

yield return new WaitForSeconds(n):程序等待n秒后从当前位置继续执行

yield new WaitForEndOfFrame():在所有的渲染以及GUI程序执行完成后从当前位置继续执行

yield new WaitForFixedUpdate():所有脚本中的FixedUpdate()函数都被执行后从当前位置继续执行

yield return WWW:等待一个网络请求完成后从当前位置继续执行

yield return StartCoroutine():等待一个协程执行完成后从当前位置继续执行

yield break:如果使用yield break语句,将会导致协程的执行条件不被满足,不会从当前的位置继续执行程序,而是直接从当前位置跳出函数体,回到函数的根部

posted @ 2019-12-26 10:43  vickylinj  阅读(474)  评论(0编辑  收藏  举报