IEnumerable、IEnumerator接口(如何增加迭代器功能)

IEnumerable、IEnumerator接口封装了迭代器功能,有了它,我们不需要将内部集合暴露出去,外界只需要访问我的迭代器接口方法即可遍历数据。

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

有两种实现迭代器的方式,一是自己继承IEnumerable接口,比较复杂;二是使用yield,简化操作,下面会有案例。

反编译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:给自己的类增加迭代器功能

 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     }

 案例2:使用yield实现迭代器功能

    public class MyCollection
    {
        private int[] list = new int[] { 1, 2, 3, 4 };

        public IEnumerator<int> GetEnumerator()
        {
            for (int i = 0; i < list.Length; i++)
            {
                yield return list[i];
            }
        }
    }
 MyCollection col = new MyCollection();
            foreach (var item in col)
            {
                Console.WriteLine(item);
            }
原文地址:https://www.cnblogs.com/fanfan-90/p/11967765.html