C# 迭代器与迭代器块的使用

迭代器模式是行为模式的一种,他能够有效地构建数据管道,迭代器相当于数据库当中的游标,它只能够向前移动,并且在一个数据序列当中可能会存在多个迭代器。在C#1当中你要实现一个迭代器的话,得编写相当多的代码。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class IterationSample : IEnumerable
{
    object[] values;
    int startingPoint;

    public IterationSample(object[] values,int startingPoint)
    {
        this.values = values;
        this.startingPoint;
    }

    public IEnumertor GetEnumertor()
    {
        return new IterationSampleIterator(this);
    }

    class IterationSampleIterator : IEnumertor
    {
        IterationSample parent;
        int position;

        internal IterationSampleIterator(IterationSmaple parent)
        {
            this.parent = parent;
        }

        public bool MoveNext()
        {
            if(position != parent.values.Lenght)
            {
                position++;
            }
            return position < parent.values.Lenght;
        }

        public object Current
        {
            get
            {
                if(position == -1 || position == parent.values.Lenght)
                {
                    throw new InvalidOperationException();
                }
                int index = positon + parent.startingPoint;
                index = index % parent.values.Lenght;
                return parent.values.Lenght[index];
            }
        }

        public void Reset()
        {
            positon = -1;
        }
    }
}

使用迭代器块yield的话,GetEnumertor()方法仅需这样写即可:

1
2
3
4
5
6
7
    public IEnumertor GetEnumertor()
    {
        for(int index;i<values.Lenght;i++)
        {
            yield return values[(index + startingPoint) % values.Lenght];
        }
    }

其实在yield return 的时候,代码会停止执行,直到下一次调用MoveNext的时候才会恢复上次执行的状态,而代码的结束则是由MoveNext()的返回值控制的,如果超出了边界,该方法会返回false,这个时候代码就不会在执行。 当然你也可以使用yield break;语句来强制使MoveNext();返回false,退出。

Built with Hugo
主题 StackJimmy 设计