普查员的初始化

时间:2018-05-23 02:07:32

标签: c# enumerator

因此,我正在慢慢阅读一本工作手册并进入有关普查员的部分。在此期间,它给出了

的示例代码
public class GameMoves
{
    private IEnumerator _cross;
    private IEnumerator _circle;

    private int i;

    public GameMoves()
    {            
        _cross = Cross();
        _circle = Circle();
        i = I();
    }
    private int _move = 0;
    const int MaxMoves = 9;

    public int I()
    {
        Console.WriteLine("Test");
        return (1);
    }

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

我从main方法运行它并创建此类的新实例。当构造函数运行_cross = Cross();时,我希望它与i = I();类似地工作,即运行类并获取返回的值。当我单步执行该程序时,它似乎根本不激活Cross()类,而是该行创建一个值为null的枚举器。只是想知道是否有人可以解释该步骤正在做什么。感谢

1 个答案:

答案 0 :(得分:1)

迭代器的重点正是你所看到的。迭代器应该推迟执行,直到实际使用结果。在您的代码中,I方法不是迭代器,因此当您调用它时,它的主体将执行完成。 Cross方法是一个迭代器,因此在使用结果之前它的主体不会被执行。

例如,如果您使用foreach循环枚举_cross,您会看到循环的每次迭代都会导致yield关键字在{Cross内被点击1}}方法。一旦命中yield break,方法就完成了,你的循环就会退出。

作为一个很好的例子,让我们比较File.ReadAllLines方法和File.ReadLines方法。前者自.NET 1.0以来一直存在,而后者是后来添加的。 ReadAllLines方法读取整个文件并将其分解为行,然后返回包含这些行的数组。这意味着在读取完整个内容之前,您无法开始处理该文件。这也意味着即使您不需要,也必须阅读全部内容。例如,如果有一百万行,并且您希望第一行包含特定单词,则即使您在第十行找到该单词,也必须读取每一行。

相比之下,ReadLines方法是一个迭代器。在您确实需要数据之前它不会开始读取文件,它只会根据需要读取数据。这意味着您可以在读取数据时处理数据,而不是等到读取数据才开始处理。这也意味着您不必再读取所需数据,例如,如果你开始寻找一个单词并在第十行找到它,那么剩余的999,990行将不会被读取。