|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- **用yield return 语句实现一个简单结合**
- - HelloCollection 类包括GetEnumerator()方法。该方法的实现代码包含两条yield return语句,它们分别返回字符串Hello和World
- ```
- using System;
- using System.Collections;
-
- namepace Wrox.ProCSharp.Arrays
- {
- public class HelloCollection
- {
- public IEnumerator<string>GetEnumerator()
- {
- yield return"HEllo";
- yield return "World";
- }
- }
- }
- 现在可以用foreach语句迭代集合
- public void HelloWord()
- {
- var helloCollection=new HelloCollection();
- foreach(var s in helloCollection)
- {
- WriteLine(s);
- }
- }
- ```
- -包含yield 语句的方法或属性也称为迭代块。迭代块必须声明为返回IEnumerator或IEnumerable接口,或者这些接口的泛型版本,这个块可以包含多条yield return语句或yield break 语句,但不能包含return语句。
- - 下面例子,可以把yield类型看做内部类Enumerator。外部类的GEtEnumerator()方法实例化并返回一个新的yield类型。在yield类型中,变量state定义了迭代的当前位置,每次调用MoveNext()时,当前位置都会改变。MoveNext()封装了迭代块的代码,并设置了current变量的值,从此使Current属性根据位置返回一个对象。
- ```
- public class HelloCollection
- {
- public IEnumerator GetEnumerator()=>new Enumerator(0);
- public class Enumerator :IEnumerator<string>,IEnumerator,IDisposable
- {
- private int_state;
- private string _current;
- public Enumerator(int state)
- {
- _state =state;
- }
- bool System.Collections.IEnumerator.MoveNext()
- {
- switch(state)
- {
- case 0:
- _current="Hello";
- _state=1;
- return true;
- case 1:
- _current="World";
- _state=2;
- return true;
- case 2:
- break;
-
- }
- return false;
- }
- void System.Collections.IEnumerator.Reset()
- {
- throw new NotSupportedException();
- }
- string System.Collections.Generic.IEnumerator<string>.Current=>current;
-
- void IDisposable.Dispose()
- {}
-
- }
- }
- ```
- > 用yield return 返回枚举器
- - 例子说明:在Tic-Tac-Toe 游戏中有9个域,玩家轮流在这些域中放置一个“十”字或一个圆。这些移动操作由GameMoves类模拟。方法Cross()和Circle()是创建迭代类型的迭代块。在Cross()迭代块中,将移动操作的信息写到控制台上,并递增移动次数。如果移动次数大于8,就用yield break停止迭代;否则,就在每次迭代中返回yield类型circle的枚举对象。Circle()迭代块非常类似于Cross()迭代块,知识它在每次迭代中返回cross迭代器类型
- ```
- public class GameMoves
- {
- private IEnumerator _cross;
- private IEnumerator _circle;
-
- public GameMoves()
- {
- _cross=Cross();
- _circle=Circle();
- }
- private int _move=0;
- const int MAxMoves=9;
-
- public IEnumerator Cross()
- {
- while (true)
- {
- WriteLine($"Cross,move {_move}");
- if(++_move >=MaxMoves)
- {
- yield break;
- }
- yield return _circle;
- }
- }
- public IEnumerator Circle()
- {
- while(true)
- {
- WriteLine($"Circle,move{move}");
- if(++_move>=MaxMoves)
- {
- yield break;
- }
- yield return _cross;
- }
- }
- }
- ```
|