




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第8章枚舉器和迭代器8.1枚舉器8.2迭代器8.1枚舉器8.1.1枚舉器概述例如,有以下代碼:int[]myarr={1,2,3,4,5};foreach(intiteminmyarr) Console.Write("{0}",item);Console.WriteLine();其輸出是:1,2,3,4,5。為什么會這樣呢?這是因為數(shù)組可以按需提供一個稱為枚舉器(enumerator,或枚舉數(shù))的對象。
枚舉器可用于依次讀取數(shù)組中的元素,但不能用于修改基礎(chǔ)集合,所以,不能用迭代變量(或枚舉變量)item修改myarr的元素。Array類有一個GetEnumerator方法用于返回當(dāng)前使用的枚舉器,除了Array類外,還有一些其他類型提供了GetEnumerator方法,凡是提供了GetEnumerator方法的類型稱為可枚舉類型,顯然,數(shù)組是可枚舉類型。8.1.2IEnumerator接口枚舉器是實現(xiàn)IEnumerator接口的類對象。IEnumerator接口支持對非泛型集合的簡單迭代,是所有非泛型枚舉器的基接口,它位于命名空間
System.Collections中。IEnumerator
接口有如下public成員:Current屬性:獲取集合中的當(dāng)前元素。MoveNext方法:將枚舉器推進(jìn)到集合的下一個元素。Reset方法:將枚舉器設(shè)置為其初始位置,該位置位于集合中第一個元素之前。最初,枚舉器被定位于集合中第一個元素的前面。Reset
方法用于將枚舉器返回到此位置。在此位置上,未定義
Current。
因此,在讀取
Current
的值之前,必須調(diào)用
MoveNext將枚舉數(shù)定位到集合的第一個元素。
再次調(diào)用MoveNext方法將
Current屬性定位到下一個元素。如果
MoveNext越過集合的末尾,則枚舉器將定位到集合中最后一個元素的后面,而且MoveNext返回
false。
對于前面的foreach語句的代碼,其執(zhí)行過程如下:調(diào)用arr.GetEnumerator()返回一個IEnumerator引用。調(diào)用所返回的IEnumerator接口的MoveNex方法。如果MoveNex方法返回true,就使用IEnumerator接口的屬性來獲取arr的一個元素,用于foreach循環(huán)。重復(fù)②和③的步驟,直到MoveNex方法返回false為止,此時循環(huán)停止。前面foreach語句代碼的功能與以下代碼是相同的:int[]myarr={1,2,3,4,5};Enumeratorie=myarr.GetEnumerator();while(ie.MoveNext()) Console.Write("{0}",ie.Current);Console.WriteLine();可枚舉類型myarr和默認(rèn)枚舉器8.1.3IEnumerable接口可枚舉類型是指提供了GetEnumerator方法的類型,而GetEnumerator方法是IEnumerable接口的成員,因此可枚舉類型是指實現(xiàn)了IEnumerable接口的類型。IEnumerable接口支持在非泛型集合上進(jìn)行簡單迭代,它位于
System.Collections命名空間。IEnumerable接口只有一個public成員,即GetEnumerator方法,用于返回一個循環(huán)訪問集合的枚舉器IEnumerator,而IEnumerator
可以通過集合循環(huán)顯示
Current
屬性和
MoveNext
和
Reset
方法?!纠?.1】設(shè)計一個學(xué)生類Student和一個People類,People類包含若干學(xué)生對象,通過從IEnumerable接口繼承使其成為可枚舉類型,并設(shè)計相應(yīng)的枚舉器類PeopleEnum(從IEnumerator接口繼承)。最后用foreach語句對People類對象執(zhí)行枚舉。usingSystem;usingSystem.Collections;namespaceproj8_1{publicclassStudent //聲明Student類{ publicintid; //學(xué)號 publicstringname; //姓名 publicStudent(intid,stringname) //構(gòu)造函數(shù) {this.id=id; =name; }}publicclassPeople:IEnumerable //聲明可枚舉類{privateStudent[]sts; //sts為Student對象數(shù)組publicPeople(Student[]pArray) //People類的構(gòu)造函數(shù),創(chuàng)建sts{ sts=newStudent[pArray.Length]; for(inti=0;i<pArray.Length;i++)sts[i]=pArray[i];}IEnumeratorIEnumerable.GetEnumerator()//實現(xiàn)IEnumerable的GetEnumerator方法{ return(IEnumerator)GetEnumerator(); //調(diào)用People類的GetEnumerator方法,并將結(jié)果轉(zhuǎn)換為枚舉器對象}publicPeopleEnumGetEnumerator()//定義People類的GetEnumerator{ returnnewPeopleEnum(sts);}}publicclassPeopleEnum:IEnumerator //聲明枚舉器類{publicStudent[]sts;intposition=-1; //位置字段,初始為-1publicPeopleEnum(Student[]list) //構(gòu)造函數(shù){ sts=list;}publicboolMoveNext()//定義PeopleEnum的MoveNext方法{position++;return(position<sts.Length);}publicvoidReset() //定義PeopleEnum的Reset方法{position=-1;}
objectIEnumerator.Current//實現(xiàn)IEnumerator的Current屬性{get{returnCurrent;}//返回PeopleEnum的Current屬性}publicStudentCurrent //定義PeopleEnum的Current屬性{get{returnsts[position];}//返回sts中position位置的Student對象}}classProgram{ staticvoidMain(){Student[]starry=newStudent[4] {newStudent(1,"Smith"),newStudent(2,"Johnson"),newStudent(3,"Mary"),newStudent(4,"Hammer")}; PeoplepeopleList=newPeople(starry);
foreach(StudentpinpeopleList) Console.WriteLine(p.id.ToString()+""+);}}}8.1.4泛型枚舉接口對于非泛型接口版本:IEnumerable接口的GetEnumerator方法返回實現(xiàn)IEnumerator枚舉器類的實例。實現(xiàn)IEnumerator枚舉器的類實現(xiàn)了Current屬性,它返回object的引用,然后需要把它轉(zhuǎn)換為實際類型的對象。對于泛型接口版本:IEnumerable<T>接口的GetEnumerator方法返回實現(xiàn)IEnumerator<T>枚舉器類的實例。IEnumerable<T>
是從
IEnumerable繼承的。實現(xiàn)IEnumerator<T>枚舉器的類實現(xiàn)了Current屬性,它返回實際類型的對象引用,不需要進(jìn)行轉(zhuǎn)換操作。IEnumerator<T>是從Enumerator繼承的。8.2迭代器8.2.1迭代器概述
迭代器(iterator)也是用于對集合如列表和數(shù)組等進(jìn)行迭代,它是一個代碼塊,按順序提供要在foreach循環(huán)中使用的所有值。
一般情況下,這個代碼塊是一個方法,稱為迭代器方法,也可以使用含
get訪問器的屬性來實現(xiàn)。這里的迭代器方法或
get
訪問器使用yield語句產(chǎn)生在foreach循環(huán)中使用的值。yield
語句的如下兩種形式:yieldreturn表達(dá)式:使用一個
yieldreturn
語句一次返回一個元素。foreach
循環(huán)的每次迭代都調(diào)用迭代器方法。
當(dāng)
遇到迭代器方法中的一個yieldreturn
語句時,返回“表達(dá)式”的值,并且保留代碼的當(dāng)前位置。當(dāng)下次調(diào)用迭代器方法時從該位置重新啟動。yieldbreak:使用
yieldbreak
語句結(jié)束迭代。在迭代器的迭代器方法或
get訪問器中,yieldreturn
語句的“表達(dá)式”類型必須能夠隱式轉(zhuǎn)換到迭代器返回類型。迭代器方法或
get
訪問器的聲明必須滿足以下要求:返回類型必須是
IEnumerable、IEnumerable<T>、IEnumerator或
IEnumerator<T>。該聲明不能有任何
ref
或out
參數(shù)。8.2.2迭代器方法迭代器方法不是在同一時間執(zhí)行所有語句,它只是描述了希望編譯器創(chuàng)建的枚舉器的行為,也就是說,迭代器方法的代碼描述了如何迭代元素。1.用迭代器方法實現(xiàn)可枚舉類型通過以下項目tmp來說明采用迭代器方法實現(xiàn)可枚舉類型的原理:usingSystem;usingSystem.Collections.Generic;namespacetmp{classProgram{ staticvoidMain(){foreach(intnumberinSomeNumbers()) Console.Write(number.ToString()+""); }publicstaticIEnumerable<int>SomeNumbers() //迭代器方法 {yieldreturn3; yieldreturn5; yieldreturn8; }}}【例8.2】設(shè)計一個程序,采用迭代器方法實現(xiàn)可枚舉類型的方式,輸出5~18之間的所有偶數(shù)。usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;namespaceProj8_2{classProgram{ publicstaticIEnumerable<int>EvenSequence(inti,intj)//迭代器方法 {for(intnumber=i;number<=j;number++) { if(number%2==0)
yieldreturnnumber; } } staticvoidMain() {foreach(intnumberinEvenSequence(5,18)) Console.Write("{0}",number); Console.WriteLine(); }}}2.用迭代器方法實現(xiàn)枚舉器可以采用創(chuàng)建枚舉器的方式,即聲明一個包含GetEnumerator方法的類,由GetEnumerator方法返回IEnumerator<int>,它通過調(diào)用迭代器方法來實現(xiàn)。前面的tmp項目采用迭代器方法實現(xiàn)枚舉器如下:usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;namespacetmp{classMyClass{ publicIEnumerator<int>GetEnumerator() {returnitmethod();} //返回枚舉器 publicIEnumerator<int>itmethod() //迭代器方法 {yieldreturn3; yieldreturn5; yieldreturn8; }} classProgram {staticvoidMain() { MyClasss=newMyClass(); foreach(intitemins) Console.Write("{0}",item); Console.WriteLine(); }}}輸出結(jié)果為358?!纠?.3】設(shè)計一個程序,采用迭代器方法實現(xiàn)枚舉器的方式,輸出100以內(nèi)的素數(shù)。namespaceProj8_3{publicclassPrimes{ intn; publicPrimes(intn) //構(gòu)造函數(shù) {this.n=n;}
publicIEnumerator<int>GetEnumerator() {returnitmethod();} //返回枚舉器
publicIEnumerator<int>itmethod() //迭代器方法 {inti,j;boolisprime; for(i=3;i<=n;i++) {isprime=true; for(j=2;j<=(int)Math.Floor(Math.Sqrt(i));j++) {if(i%j==0) {isprime=false; break; }}if(isprime)yieldreturni; }}} classProgram {staticvoidMain(string[]args) { inti=1; Primesps=newPrimes(100); Console.WriteLine("100以內(nèi)素數(shù):");
foreach(intiteminps) {Console.Write("{0,4:d}",item); if(i%10==0)//某輸出10個整數(shù)換一行 Console.WriteLine(); i++; } Console.WriteLine(); } }}從上看出,當(dāng)創(chuàng)建類的迭代器時,不必實現(xiàn)整個
IEnumerator
接口,當(dāng)編譯器檢測到迭代器時,會自動生成
Current屬性、MoveNext方法和
IEnumerator
或
IEnumerator<T>
接口的
Dispose
方法。
注意迭代器不支持
IEnumerator.Reset
方法,如果要重置迭代器,必須獲取新的迭代器。因此使用迭代器方法大大簡化了可枚舉類型和枚舉器的設(shè)計過程。8.2.3get訪問器使用get訪問器就是將迭代器作為屬性。在屬性的get訪問器中使用yieldreturn語句,這樣該屬性可以代替迭代器方法,將其返回的對象作為枚舉器。例如,前面的tmp項目采用get訪問器方式設(shè)計如下:usingSystem;usingSystem.Collections.Generic;namespacetmp{classProgram{ staticvoidMain() {foreach(intnumberinAttr) Console.Write(number.ToString()+""); }
publicstaticIEnumerable<int>Attr//含yieldreturn語句的屬性 {get { int[]myarr={3,5,8}; for(inti=0;i<=2;i++)
yieldreturnmyarr[i]; } }}}
【例8.5】修改例8.4的程序,增加一個正向迭代列表容器中元素的屬性和一個反向迭代列表容器中元素的屬性。usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;namespaceProj8_5{publicclassMyClass<T>:IEnumerable<T>//聲明可枚舉泛型類{ privateT[]data=newT[100]; privateintlength=0; publicvoidAdd(Te) //添加元素e {data[length]=e; length++; } IEnumeratorIEnumerable.GetEnumerator() {returnGetEnumerator();}
publicIEnumerator<T>GetEnumerator()//迭代器方法 {for(inti=0;i<=length-1;i++)
yieldreturndata[i]; }
publicIEnumerable<T>Positive {get { returnthis;} }
publicIEnumerable<T>Reverse //含yield
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 ISO/IEC 19785-3:2025 EN Information technology - Common Biometric Exchange Formats Framework - Part 3: Patron format specifications
- 華科數(shù)控技術(shù)課件網(wǎng)址
- 健康老齡化課件
- 杭州高中模擬數(shù)學(xué)試卷
- 湖南8年級下冊數(shù)學(xué)試卷
- 2024-2030年中國冬棗行業(yè)市場深度分析及發(fā)展趨勢預(yù)測報告
- 2021-2026年中國EHPS電液泵市場深度分析及投資戰(zhàn)略咨詢報告
- 健康科普知識課件
- 健康科學(xué)減脂課件
- 2023-2028年中國混合云管理行業(yè)市場全景評估及投資規(guī)劃建議報告
- 采棉機操作手冊和維護指南
- 放射狀角膜切開術(shù)并發(fā)癥的長期隨訪研究-全面剖析
- Excel表格公式培訓(xùn)
- 2025年山西省華遠(yuǎn)國際陸港集團有限公司招聘筆試參考題庫含答案解析
- 塞爾維亞語教學(xué)與學(xué)習(xí)作業(yè)指導(dǎo)書
- 農(nóng)商銀行貸款合同電子版
- 翼狀胬肉術(shù)后護理
- 關(guān)于麻將館的創(chuàng)業(yè)計劃書
- 《目視化管理》課件
- ERP車間管理模塊操作培訓(xùn)手冊
- 機械制造項目檢測試驗計劃
評論
0/150
提交評論