程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c#列舉和迭代器

c#列舉和迭代器

編輯:C#入門知識

列舉 - Enumeration

迭代器是一個值序列(集合)上的一個只讀且只向前移動的游標。迭代器要麼實現了IEnumerator接口,要麼實現了IEnumerator<T>接口。

從技術的角度看,如果一個對象有MoveNext方法以及Current屬性,那麼我們就可以將其看作一個迭代器。

我們可以使用foreach語句去迭代一個可列舉對象。可迭代的對象其實就是一個序列的邏輯體現。可列舉的對象不但自身就是一個游標,而且它還可以生成一個游標迭代自己。因此,可列舉的對象有兩個特性

  • 實現IEnumerator接口,或實現IEnumerator<T>接口
  • 有一個方法GetEnumerator,該方法返回一個迭代器

列舉模式:

Enumeration pattern

為了更好的理解上面的概率和模式,我們來看下面的兩個例子

Sample 1 Sample 2

Sample1采取了foreach這樣的高級方式去迭代字符串(因為字符串類實現了CharEnumerator);而Sample2則使用了底層的方式完成對字符串的迭代。 對於Sample我們使用了using語句,這是因為CharEnumerator實現了IDisposable接口,下面的代碼顯示了CharEnumrator的大部分代碼(來自微軟官方)

CharEnumerator

初始化集合

我們可使用一行語句實例一個可列舉的對象。比如:IList<Int> list = new List<int>{1,2,3};編譯時,編譯器會自動翻譯為:

Translated Code

這是因為該列舉對象實現了IEnumerable接口,而且還包含了Add方法。
為了驗證此點,我們可以通過查看IL代碼的方式來確認:

IL Code

迭代器 - Iterator

既然foreach可應用於列舉,那麼一個列舉可以生成一個迭代器。很繞口很困惑是吧,我們先來看下面的例子:使用迭代器返回斐波納契數列

Fibonacci

請注意,在上面的代碼中,我們使用了yield return。那麼它和return有什麼區別呢?
return:從方法中返回一個值
yield return:從當前的迭代器中生成下一個元素。yield語句每執行一次,程序的控制權就退還給調用者,而被調用者的狀態仍然保留,這就使得方法在調用者列舉下一個元素的時候能繼續執行。被調用者的狀態的生命周期取決於列舉,正因為如此,當調用者完成列舉後,被調用者的狀態得以釋放。

迭代器語法

迭代器可以是包含了一個或多個yield語句的方法、屬性、或所引器。迭代器必須返回下面四個類型之一:IEnumerable, IEnumerable<T>, IEnumerator, IEnumerator<T>

再繼續下一步之前,我們看一下IEnumerable接口和IEnumerator的定義

IEnumerator & IEnumerable

迭代器與列舉有不一樣的語法,在於迭代器需要返回可列舉的接口或者列舉器接口。

創建序列

迭代器可以進一步用於創建迭代。為了證實這點,我們可以擴展我們斐波納契數列例子

Composable Iterator

請注意,直到Fibonacci方法所產生的數列的MoveNext()方法被調用時(執行foreach循環,會隱式地調用IEnumerator的MoveNext方法),才會判斷該元素是否為偶數。

迭代器可以進一步用於創建迭代大量應用於LINQ。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved