C#迭代器和Unity的Coroutine原理

Enumeration

它提供了foreach对集合进行遍历的机制,它由两部分组成:enumerator和enumerable object。

enumerator是指向一个序列的光标,它是只读的、只能向前的。需要实现下面两个接口之一:

  • System.Collections.IEnumerator
  • System.Collections.Generic.IEnumerator

foreach语句就是在一个enumerable object上进行遍历。它是一个序列的逻辑表示,它产生一个指向自己的光标。需要实现下面两个接口之一:

  • Implements IEnumerable or IEnumerable
  • Has a method named GetEnumerator that returns an enumerator

这个模式的示例如下:

class Enumerator // Typically implements IEnumerator or IEnumerator<T>
{
   
    
    
 public IteratorVariableType Current {
   
    
     get {
   
    
    ...} }
 public bool MoveNext() {
   
    
    ...}
}
class Enumerable // Typically implements IEnumerable or IEnumerable<T>
{
   
    
    
 public Enumerator GetEnumerator() {
   
    
    ...}
}

一个高维度的遍历代码如下:

foreach (char c in "beer")
 Console.WriteLine (c);

它的底层实现如下:

using (var enumerator = "beer".GetEnumerator())
 while (enumerator.MoveNext())
 {
   
    
    
 var element = enumerator.Current;
 Console.WriteLine (element);
 }

Iterators/迭代器

foreach是enumerator的使用者,iterator则是enumerator的生产者。如下代码:

using System;
using System.Collections.Generic;
class Test
{
   
    
    
	 static void Main()
	 {
   
    
    
		 foreach (int fib in Fibs(6))
		 Console.Write (fib + " ");
	 }
	 static IEnumerable<int> Fibs (int fibCount)
	 {
   
    
    
		 for (int i = 0, prevFib = 1