1. 程式人生 > >迭代器的實現與原理

迭代器的實現與原理

說起迭代器我們對它的印象大概就是能夠使用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