IEnumerable、IEnumerator接口(自定义foreach)

在C#中,使用foreach语句来遍历集合。foreach语句是微软提供的语法糖,使用它可以简化C#内置迭代器的使用复杂性。编译foreach语句,会生成调用GetEnumerator和MoveNext方法以及Current属性的代码。

反编译foreach,生成类似下面这段代码:

1 IEnumerator<Student> studentEnumerator = studentList.GetEnumerator();
2 while (studentEnumerator.MoveNext())
3 {
4      var currentStudent = studentEnumerator.Current as Student;
5      Console.WriteLine("Id = {0}, Name = {1}, Age = {2}", currentStudent.Id, currentStudent.Name, currentStudent.Age);
6 }

案例:给自己的类增加迭代器功能

 1     public class StudentSet : IEnumerable
 2     {
 3         private Student[] students;
 4         public StudentSet(Student[] inputStudents)
 5         {
 6             students = new Student[inputStudents.Length];
 7             for (int i = 0; i < inputStudents.Length; i++)
 8             {
 9                 students[i] = inputStudents[i];
10             }
11         }
12 
13         IEnumerator IEnumerable.GetEnumerator()
14         {
15             return (IEnumerator)GetEnumerator();
16         }
17 
18         public StudentEnumerator GetEnumerator()
19         {
20             return new StudentEnumerator(students);
21         }
22     }
23 
24     public class StudentEnumerator : IEnumerator
25     {
26         public Student[] students;
27         int position = -1;
28         public StudentEnumerator(Student[] students)
29         {
30             this.students = students;
31         }
32 
33         public bool MoveNext()
34         {
35             position++;
36             return (position < students.Length);
37         }
38 
39         public void Reset()
40         {
41             position = -1;
42         }
43 
44         object IEnumerator.Current
45         {
46             get
47             {
48                 return Current;
49             }
50         }
51 
52         public Student Current
53         {
54             get
55             {
56                 try
57                 {
58                     return students[position];
59                 }
60                 catch (IndexOutOfRangeException)
61                 {
62                     throw new InvalidOperationException();
63                 }
64             }
65         }
66     }

猜你喜欢

转载自www.cnblogs.com/fanfan-90/p/11967765.html