关于这个例子使用yield语句还可以完成更复杂的任务,例如从yield return中返回枚举器。
在TicTacToe游戏中有9个域,玩家轮流在这些域中放置“十”字或一个圆。这些移动操作由GameMoves类模拟。方法Cross()和Circle()是创建迭代类型的迭代块。变量cross和circle在GameMoves类的构造函数中设置为Cross()和Circle()方法。这些域不设置为调用的方法,而是设置为用迭代块定义的迭代类型。在Cross()迭代块中,将移动操作的信息写到控制台上,并递增移动次数。如果移动次数大于9,就用yield break停止迭代;否则,就在每次迭代中返回yield类型cross的枚举对象。Circle()迭代块非常类似于Cross()迭代块,只是它在每次迭代中返回circle迭代类型。public class GameMoves
{
    private IEnumerator cross;
    private IEnumerator circle;    public GameMoves()
    {
        cross = Cross();
        circle = Circle();
    }    private int move = 0;    public IEnumerator Cross()
    {
        while (true) //这个位置是死循环
        {
            Console.WriteLine("Cross, move {0}", move);
            move++;
            if (move > 9)
                yield break;//yield break 可以中断循环吗???
            yield return circle;
        }
    }    public IEnumerator Circle()
    {
        while (true) //这个位置是死循环
        {
            Console.WriteLine("Circle, move {0}", move);
            move++;
            if (move > 9)
                yield break;
            yield return cross;
        }
    }
}在客户程序中,可以以如下方式使用GameMoves类。将枚举器设置为由game.Cross()返回的枚举器类型,以设置第一次移动。enumerator.MoveNext调用以迭代块定义的一次迭代,返回另一个枚举器。返回的值可以用Current属性访问,并设置为enumerator变量,用于下一次循环:
GameMoves game = new GameMoves();
IEnumerator enumerator = game.Cross();
while (enumerator.MoveNext())
{
  enumerator = (IEnumerator) enumerator.Current;
}这个程序的输出会显示交替移动的情况,直到最后一次移动:
Cross, move 0
Circle, move 1
Cross, move 2
Circle, move 3
Cross, move 4
Circle, move 5
Cross, move 6
Circle, move 7
Cross, move 8
这个例子太难了 求解释下

解决方案 »

  1.   

    呵呵,看下面的例子:public IEnumerable<int> GetEvens(int n)
    {
        for (int i = 0; i < n; i++)
        {
            if (i % 2 == 0) yield return i;
        }
    }// 以下等价public IEnumerable<int> GetEvens(int n)
    {
        var list = new List<int>();
        for (int i = 0; i < n; i++)
        {
            if (i % 2 == 0) list.Add(i);
        }
        return list;
    }