6.2 C# 2:利用 yield 語句簡化迭代器
阿新 • • 發佈:2018-11-25
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 }