位置:首頁 > 軟件操作教程 > 編程開發(fā) > C# > 問題詳情

C# 迭代器

提問人:劉團(tuán)圓發(fā)布時(shí)間:2020-12-07

    Enumerable接口允許使用foreach循環(huán)。在foreach循環(huán)中并不是只能使用集合類,相反,在foreach循環(huán)中使用定制類通常有很多優(yōu)點(diǎn)。

    但是,重寫使用foreach循環(huán)的方式或者提供定制的實(shí)現(xiàn)方式并不一定很簡(jiǎn)單。為了說明這一點(diǎn),下面有必要深入研究一下foreach循環(huán)。在foreach循環(huán)中,迭代一個(gè)collectionObject集合的過程如下:

(1)調(diào)用 collectionObjectGetEnumeratorO,返回一個(gè)Enumerator引用。這個(gè)方法可通過IEnumerable接口的實(shí)現(xiàn)代碼來獲得,但這是可選的。

(2)調(diào)用所返回的IEnumerator接口的MoveNextQ方法。

(3)如果MoveNextO方法返回true,就使用IEnumerator接口的Current屬性來獲取對(duì)象的一個(gè)引用,用于 foreach 循環(huán)。

(4)重復(fù)前面兩步,直到MoveNextO方法返回felse為止,此時(shí)循環(huán)停止。

    所以,為在類中進(jìn)行這些操作,必須重寫幾個(gè)方法,跟蹤索引,維護(hù)Qirrent屬性,以及執(zhí)行其他一些操作。這要做許多工作。

    —個(gè)較簡(jiǎn)單的替代方法是使用迭代器。使用迭代器將有效地自動(dòng)生成許多代碼,正確地完成所有任務(wù)。而且,使用迭代器的語法掌握起來非常容易。

    迭代器的定義是,它是一個(gè)代碼塊,按順序提供了要在foreach塊中使用的所有值。一般情況下,這個(gè)代碼塊是一個(gè)方法,但也可以使用屬性訪問器和其他代碼塊作為迭代器。這里為簡(jiǎn)單起見,僅介紹方法。

    無論代碼塊是什么,其返回類型都是有限制的。與期望正好相反,這個(gè)返回類型與所枚舉的對(duì)象類型不同。例如,在表示Animal對(duì)象集合的類中,迭代器塊的返回類型不可能是Animal。兩種可能的返回類型是前面提到的接口類型:IEnumerable和IEnumerator。使用這兩種類型的場(chǎng)合是:

    ?如果要迭代一個(gè)類,則使用方法GetEnumerator(),其返回類型是IEnumerator。

    ?如果要迭代一個(gè)類成員,例如一個(gè)方法,則使用IEnumerable。

在迭代器塊中,使用yield關(guān)鍵字選擇要在foreach循環(huán)中使用的值。其語法如下:

    yield return <value>;

利用這個(gè)信息就足以建立一個(gè)非常簡(jiǎn)單的示例,如下所示(該示例包含在代碼文件SimpleIterators\Program.cs中):

public static IEnumerable SimpleList()

{

    yield return "string 1"; 

    yield return "string 2"; 

    yield return "string 3";

}

static void Main(string[] args)

{

    foreach (string item in SimpleList())

        WriteLine (item);

    ReadKey();

}

    在此,靜態(tài)方法SimpleListO就是迭代器塊。它是一個(gè)方法,所以使用IEnumerable返回類型。SimpleList()使用yieid關(guān)鍵字為使用它的foreach塊提供了 3個(gè)值,每個(gè)值都輸出到屏幕上,結(jié)果如圖所示。

image.png

    顯然,這個(gè)迭代器并不是特別有用,但它確實(shí)能夠演示迭代器的機(jī)制,說明實(shí)現(xiàn)迭代器有多么簡(jiǎn)單??纯创a,讀者可能會(huì)疑惑代碼是如何知道返回string類型的項(xiàng)。實(shí)際上,并沒有返回string類型的項(xiàng),而是返回object類型的值。因?yàn)閛bject是所有類型的基類,所以可從yield語句中返回任意類型。

    但編譯器的智能程度很高,所以我們可以把返回值解釋為foreach循環(huán)需要的任何類型。這里代碼需要string類型的值,而這正是我們要使用的值。如果修改一行yield代碼,讓它返回一個(gè)整數(shù),就會(huì)在foreach循環(huán)中出現(xiàn)一個(gè)類型轉(zhuǎn)換異常。


對(duì)于迭代器,還有一點(diǎn)要注意??梢允褂孟旅娴恼Z句中斷將信息返回給foreach循環(huán)的過程:

    yield break;

在遇到迭代器中的這個(gè)語句時(shí),迭代器的處理會(huì)立即中斷,使用該迭代器的foreach循環(huán)也一樣。


繼續(xù)查找其他問題的答案?

相關(guān)視頻回答
回復(fù)(0)
返回頂部