1. 程式人生 > >6.2 C# 2:利用 yield 語句簡化迭代器

6.2 C# 2:利用 yield 語句簡化迭代器

 

 

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             object[] values = new object[] { "a", "b", "c", "d", "e" };
 6             IterationSample sample = new IterationSample(values, 3);
 7             foreach (var item in sample)
8 { 9 Console.WriteLine(item); 10 } 11 Console.ReadKey(); 12 } 13 } 14 public class IterationSample : IEnumerable 15 { 16 public object[] values; 17 int startPoint; 18 public IterationSample(object
[] values, int startingPoint) 19 { 20 this.values = values; 21 this.startPoint = startingPoint; 22 } 23 public IEnumerator GetEnumerator() 24 { 25 //return new IterationSampleIterator(this); 26 for (int index = 0; index < values.Length; index++)
27 { 28 yield return values[(index + startPoint) % values.Length]; 29 } 30 } 31 } 32 public class IterationSampleIterator : IEnumerator 33 { 34 IterationSample parent; 35 int position; 36 public IterationSampleIterator(IterationSample parent) 37 { 38 this.parent = parent; 39 this.position = -1; 40 } 41 public object Current 42 { 43 get 44 { 45 if (position == -1 || position == parent.values.Length) 46 { 47 throw new InvalidOperationException(); 48 } 49 int index = position + parent.values.Length; 50 index = index % parent.values.Length; 51 return parent.values[index]; 52 } 53 } 54 55 public bool MoveNext() 56 { 57 if (position != parent.values.Length) 58 { 59 position++; 60 } 61 return position < parent.values.Length; 62 } 63 64 public void Reset() 65 { 66 position = -1; 67 } 68 }

6.2.2 觀察迭代器的工作流程

 

 1     class Program
 2     {
 3         static readonly string Padding = new string(' ', 30);
 4         static void Main(string[] args)
 5         {
 6             IEnumerable<int> iterable = CreatteEnumerable(Padding);
 7             IEnumerator<int> iterator = iterable.GetEnumerator();
 8             Console.WriteLine("starting iterate");
 9 
10             while (true)
11             {
12                 Console.WriteLine("calling MoveNext()");
13                 bool result = iterator.MoveNext();
14                 Console.WriteLine("moveNext result={0}", result);
15                 if (!result)
16                     break;
17                 Console.WriteLine("fetching current");
18                 Console.WriteLine("current result ={0}", iterator.Current);
19             }
20 
21             Console.ReadKey();
22         }
23         static IEnumerable<int> CreatteEnumerable(string Padding)
24         {
25             Console.WriteLine("{0} start of createEnumerbale padding", Padding);
26 
27             for (int i = 0; i < 3; i++)
28             {
29                 Console.WriteLine("{0} about to yield {1}", Padding, i);
30                 yield return i;
31                 Console.WriteLine("{0} after padding", Padding);
32             }
33             Console.WriteLine("{0} yield final value ", Padding);
34             yield return -1;
35             Console.WriteLine("{0} end of createEnumerable();", Padding);
36         }
37         /*
38         
39         starting iterate
40         calling MoveNext()
41                                        start of createEnumerbale padding
42                                        about to yield 0
43         moveNext result=True
44         fetching current
45         current result =0
46         calling MoveNext()
47                                        after padding
48                                        about to yield 1
49         moveNext result=True
50         fetching current
51         current result =1
52         calling MoveNext()
53                                        after padding
54                                        about to yield 2
55         moveNext result=True
56         fetching current
57         current result =2
58         calling MoveNext()
59                                        after padding
60                                        yield final value
61         moveNext result=True
62         fetching current
63         current result =-1
64         calling MoveNext()
65                                        end of createEnumerable();
66         moveNext result=False
67 
68          */
69     }