迭代器的實現與原理
阿新 • • 發佈:2018-12-24
說起迭代器我們對它的印象大概就是能夠使用foreach關鍵字來遍歷一個集合,還必須實現IEnumerable或IEnumerable<T>介面,實現裡面的GetEnumerator方法。那麼具體是怎樣的呢?
其實迭代器跟資料庫的遊標非常相似,讀取方式就是一直往下讀,直到讀完為止。下面我們來介紹C#是如何實現這個迭代器的步驟:
首先,我們要找到這個物件
然後,開啟這個迭代器(GetEnumerator)
找到這個物件的第一條物件(Current),和這個開始物件的位置
接著一直往下讀(MoveNext),直到讀完這個索引器
最後釋放這個迭代器(Dispose() )
程式碼實現:
首先定義這個物件
public class Student
{
public string Name { get; set; }
public Student(string name)
{
this.Name = name;
}
}
定義這個構造器,實現MoveNext(),Current,Reset()屬性和方法。
/// <summary> /// 自定義一個迭代器 /// </summary> public class StudentEnumerator : IEnumerator { private int index; private Student current; private StudentList studentList; public StudentEnumerator(StudentList studentList) { //注入 this.studentList = studentList; index = 0; } public object Current => this.current; public bool MoveNext() { if (index+1>studentList.Count) { return false; } else { this.current = studentList[index]; index++; return true; } } public void Reset() { index = 0; } }
然後我們實現這個IEnumerable介面
public class StudentList : IEnumerable { private Student[] students; public StudentList(Student[] student) { //構造注入 this.students = student; } //索引器 public Student this[int index] { get { return students[index]; } } //長度 public int Count { get { return students.Length; } } //實現GetEnumerator方法,返回迭代器IEnumerator public IEnumerator GetEnumerator() { return new StudentEnumerator(this); } }
最後我們呼叫它
static void Main(string[] args)
{
Student[] student ={
new Student("張三"),
new Student("李四"),
new Student("王麻子")
};
StudentList studentList = new StudentList(student);
foreach (Student s in studentList)
{
Console.WriteLine("當前學生姓名:{0}", s.Name);
}
Console.Read();
}
輸出:
當前學生姓名:張三
當前學生姓名:李四
當前學生姓名:王麻子
在C#2.0中微軟用yield來簡化了迭代器的寫法,開發人員只需要在實現GetEnumerator方法的時候用yield return就可以實現這個方法,所以yield就是一個語法糖,c#有非常多的語法糖
//實現GetEnumerator方法,返回迭代器IEnumerator
public IEnumerator GetEnumerator()
{
//return new StudentEnumerator(this);
for (int index = 0; index < students.Length; index++)
{
yield return students[index];
}
}
那麼現在我們來分解foreach (Student s in studentList),
studentList呼叫GetEnumerator()方法,in 呼叫了MoveNext()方法,Student就是這個迭代的物件Current