这里涉及两个接口,IEnumerable和 IEnumerator。通过实现这两个接口,就可以了。
下面给出一个简单的Demo
1
using
System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Collections;
6
7 namespace CustomCollection
8 {
9 public class Person
10 {
11 public string fname;
12 public string lname;
13 public Person(string first, string second)
14 {
15 this.fname = first;
16 this.lname = second;
17 }
18 public override string ToString()
19 {
20 return this.fname + " " + this.lname;
21 }
22 }
23 public class People : IEnumerable
24 {
25
26 IEnumerable Members#region IEnumerable Members
27
28 public IEnumerator GetEnumerator()
29 {
30 return new PeopleEnum(_people);
31 }
32
33 #endregion
34
35 private Person[] _people;
36
37 public People(Person[] people)
38 {
39 _people = new Person[people.Length];
40 for (int i = 0; i < people.Length; i++)
41 {
42 _people[i] = people[i];
43 }
44 }
45 }
46 public class PeopleEnum : IEnumerator
47 {
48 public Person[] list;
49 private int position = -1;
50 public PeopleEnum(Person[] people)
51 {
52 list = people;
53 }
54
55 IEnumerator Members#region IEnumerator Members
56
57 public object Current
58 {
59 get
60 {
61 try
62 {
63 return list[position];
64 }
65 catch (IndexOutOfRangeException e)
66 {
67 throw new Exception("Out of Range");
68 }
69 }
70 }
71
72 public bool MoveNext()
73 {
74 position++;
75 return (position < list.Length);
76 }
77
78 public void Reset()
79 {
80 position = -1;
81 }
82
83 #endregion
84 }
85 public class CustomCollection
86 {
87 static void Main(string[] args)
88 {
89 Person[] peopleArray = new Person[3]
90 {
91 new Person("John", "Smith"),
92 new Person("Jim", "Johnson"),
93 new Person("Sue", "Rabon"),
94 };
95
96 People peopleList = new People(peopleArray);
97 foreach (Person p in peopleList)
98 Console.WriteLine(p);
99 }
100 }
101}
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Collections;
6
7 namespace CustomCollection
8 {
9 public class Person
10 {
11 public string fname;
12 public string lname;
13 public Person(string first, string second)
14 {
15 this.fname = first;
16 this.lname = second;
17 }
18 public override string ToString()
19 {
20 return this.fname + " " + this.lname;
21 }
22 }
23 public class People : IEnumerable
24 {
25
26 IEnumerable Members#region IEnumerable Members
27
28 public IEnumerator GetEnumerator()
29 {
30 return new PeopleEnum(_people);
31 }
32
33 #endregion
34
35 private Person[] _people;
36
37 public People(Person[] people)
38 {
39 _people = new Person[people.Length];
40 for (int i = 0; i < people.Length; i++)
41 {
42 _people[i] = people[i];
43 }
44 }
45 }
46 public class PeopleEnum : IEnumerator
47 {
48 public Person[] list;
49 private int position = -1;
50 public PeopleEnum(Person[] people)
51 {
52 list = people;
53 }
54
55 IEnumerator Members#region IEnumerator Members
56
57 public object Current
58 {
59 get
60 {
61 try
62 {
63 return list[position];
64 }
65 catch (IndexOutOfRangeException e)
66 {
67 throw new Exception("Out of Range");
68 }
69 }
70 }
71
72 public bool MoveNext()
73 {
74 position++;
75 return (position < list.Length);
76 }
77
78 public void Reset()
79 {
80 position = -1;
81 }
82
83 #endregion
84 }
85 public class CustomCollection
86 {
87 static void Main(string[] args)
88 {
89 Person[] peopleArray = new Person[3]
90 {
91 new Person("John", "Smith"),
92 new Person("Jim", "Johnson"),
93 new Person("Sue", "Rabon"),
94 };
95
96 People peopleList = new People(peopleArray);
97 foreach (Person p in peopleList)
98 Console.WriteLine(p);
99 }
100 }
101}
通过调试发现,Reset似乎没有被调用,到博客园搜了一下,验证了自己的判断,看到了一个文章
http://www.cnblogs.com/Daview/archive/2006/09/15/505317.html
不看不知道,以前有被问到如何实现自定义的集合支持foreach遍历,当时脱口而出实现那个两个接口。现在看来,这真的是初学者的无知,不是简单定义一个类型实现IEnumerable和IEnumerator就可以了。受Reset没被调用的影响,应该定义两个类型分别实现接口,否则就会出现集合遍历第二遍的失败。