yield return疑问

aa81758175 2012-07-13 10:56:51

关于这个例子

使用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


这个例子太难了 求解释下




...全文
149 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
youzelin 2012-07-27
  • 打赏
  • 举报
回复
结贴啊~~~~
youzelin 2012-07-13
  • 打赏
  • 举报
回复
呵呵,看下面的例子:

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;
}

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧