1 /*
2 IEnumerator 接口
3 支持对非泛型集合的简单迭代。
4
5 IEnumerator 是所有非泛型枚举数的基接口。
6
7
8 C# 语言的 foreach 语句(在 Visual Basic 中为 for each)隐藏了枚举数的复杂性。
9
10 枚举数可用于读取集合中的数据,但不能用于修改基础集合。
11
12 最初,枚举数定位在集合中第一个元素前。Reset 方法还会将枚举数返回到此位置。在此位置,调用 Current 属性会引发异常。因此,在读取 Current 的值之前,必须调用 MoveNext 方法将枚举数提前到集合的第一个元素。
13
14 在调用 MoveNext 或 Reset 之前,Current 返回同一对象。MoveNext 将 Current 设置为下一个元素。
15
16 如果 MoveNext 越过集合的末尾,则枚举数将被放置在此集合中最后一个元素的后面,而且 MoveNext 返回 false。当枚举数位于此位置时,对 MoveNext 的后续调用也返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。若要再次将 Current 设置为集合的第一个元素,可以调用 Reset,然后再调用 MoveNext。
17
18 只要集合保持不变,枚举数就保持有效。如果对集合进行了更改(如添加、修改或删除元素),则枚举数将失效且不可恢复,并且下一次对 MoveNext 或 Reset 的调用将引发 InvalidOperationException。如果在 MoveNext 和 Current 之间修改集合,那么即使枚举数已经无效,Current 也将返回它所设置成的元素。
19
20 枚举数没有对集合的独占访问权;因此,枚举通过集合在本质上不是一个线程安全的过程。即使一个集合已进行同步,其他线程仍可以修改该集合,这将导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。
21 */
22
23
24 using System;
25 using System.Collections.Generic;
26 using System.Collections;
27 using System.Linq;
28 using System.Text;
29
30 namespace ConsoleApplication1
31 {
32 public class Person
33 {
34 public Person(string fName, string lName)
35 {
36 this.firstName = fName;
37 this.lastName = lName;
38 }
39
40 public string firstName;
41 public string lastName;
42 }
43
44 public class People : IEnumerable
45 {
46 private Person[] _people;
47 public People(Person[] pArray)
48 {
49 _people = new Person[pArray.Length];
50
51 for (int i = 0; i < pArray.Length; i++)
52 {
53 _people[i] = pArray[i];
54 }
55 }
56
57 public IEnumerator GetEnumerator()
58 {
59 for (int i = 0; i < _people.Length; i++) {
60 yield return _people[i];
61 }
62 }
63 }
64
65 class App
66 {
67 static void Main()
68 {
69 Person[] peopleArray = new Person[3]
70 {
71 new Person("John", "Smith"),
72 new Person("Jim", "Johnson"),
73 new Person("Sue", "Rabon"),
74 };
75
76 People peopleList = new People(peopleArray);
77 foreach (Person p in peopleList)
78 Console.WriteLine(p.firstName + " " + p.lastName);
79
80 List<Product> ps = new List<Product>() {
81 new Product(){ ProductName="笔记本", ProductPrice=3000.00M},
82 new Product(){ ProductName="小本", ProductPrice=2000.00M},
83 new Product(){ ProductName="小小本", ProductPrice=1900.00M}
84 };
85
86
87
88 IEnumerable cheaperPs = GetSpecialProduct(ps);
89
90 foreach (var g in cheaperPs)
91 {
92 Console.WriteLine(((Product)g).ProductName + ":" + ((Product)g).ProductPrice);
93 }
94
95 }
96
97 static IEnumerable GetSpecialProduct(List<Product> gs)
98 {
99 foreach (var g in gs)
100 {
101 if (g.ProductPrice <= 2000)
102 {
103 yield return g;
104 }
105 }
106 }
107
108 static List<Product> GetSpecialProductOld(List<Product> gs)
109 {
110 List<Product> pps = new List<Product>();
111 foreach (var g in gs)
112 {
113 if (g.ProductPrice <= 2000)
114 {
115 pps.Add(g);
116 }
117 }
118 return pps;
119 }
120
121
122 }
123 class Product
124 {
125 public string ProductName
126 { get; set; }
127 public decimal? ProductPrice
128 {
129 get;
130 set;
131 }
132 }
133
134 }