迭代器匿名方法和_第1頁
迭代器匿名方法和_第2頁
迭代器匿名方法和_第3頁
迭代器匿名方法和_第4頁
迭代器匿名方法和_第5頁
已閱讀5頁,還剩20頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第17章迭代器、匿名方法和擴(kuò)展方法迭代器、匿名方法和擴(kuò)展方法出現(xiàn)使得代碼更清楚,書寫更簡便。迭代器是一個語句塊,它能夠產(chǎn)生一系列有序值,從而使得foreach語句能夠訪問該序列。匿名方法是一個特殊方法,它能夠省略方法名稱。擴(kuò)展方法能夠向現(xiàn)有類型“添加”新方法,它是一個靜態(tài)方法,經(jīng)過擴(kuò)展類型實例來調(diào)用擴(kuò)展方法。本章將給大家詳細(xì)講解C#語言中迭代器、匿名方法和擴(kuò)展方法。迭代器匿名方法和第1頁17.1使用迭代器迭代器(iterator)是一個產(chǎn)生有序值序列語句塊,其作用是使遍歷過程變得愈加輕易。它返回一組對象組員,可用作方法、運算符或存放器。比如,假定某個數(shù)組有5個組員,則該數(shù)組迭代器將返回這5個元素,每次返回一個元素。經(jīng)過創(chuàng)建迭代器,能夠在foreach循環(huán)中使用類對象。迭代器匿名方法和第2頁迭代器中使用關(guān)鍵字是yield,這個關(guān)鍵字只在迭代器中才有特定含義。迭代器包含兩個特有語句是yieldreturn語句和yieldbreak語句。yieldreturn語句能夠產(chǎn)生迭代下一個值,而yieldbreak語句則指示迭代完成。當(dāng)?shù)鲌?zhí)行到y(tǒng)ieldreturn語句時,會保留當(dāng)前位置。假如該迭代器再次被調(diào)用,將從保留位置開始執(zhí)行。注意:迭代器返回類型必須為(可枚舉接口)IEnumerable、(枚舉器接口)IEnumerator、IEnumerable<T>或Ienumeraor<T>。迭代器分為非泛型迭代器和泛型迭代器,下面我們來學(xué)習(xí)這兩種迭代器。迭代器匿名方法和第3頁17.1.1創(chuàng)建非泛型迭代器創(chuàng)建一個非泛型迭代器最慣用方法是實現(xiàn)IEnumerable接口GetEnumerator()方法。IEnumerable接口表示公開枚舉數(shù),該枚舉數(shù)支持在非泛型集合上進(jìn)行簡單迭代。IEnumerable接口只包含GetEnumerator()方法,它返回一個循環(huán)訪問集合枚舉數(shù)。【示例17-1】下面在Program類中創(chuàng)建一個非泛型迭代器,Program類必須滿足以下兩個條件。實現(xiàn)IEnumerable接口。實現(xiàn)IEnumerable接口GetEnumerator()方法。迭代器匿名方法和第4頁Program類實現(xiàn)了IEnumerable接口GetEnumerator()方法,并在for語句中使用yieldreturn語句創(chuàng)建迭代器每一個元素。注意:正是因為Program類實現(xiàn)了IEnumerable接口GetEnumerator()方法,從而使得Program為可枚舉類型,所以,能夠使用foreach語句遍歷Program類型實例。迭代器匿名方法和第5頁17.1.2創(chuàng)建泛型迭代器創(chuàng)建一個泛型迭代器,需要實現(xiàn)IEnumerable和IEnumerable<T>接口GetEnumerator()方法?!臼纠?7-2】下面在Program2<T>泛型類中創(chuàng)建一個泛型迭代器,Program2<T>類必須滿足以下3個條件。實現(xiàn)IEnumerable<T>接口。實現(xiàn)IEnumerable<T>接口GetEnumerator()方法。實現(xiàn)IEnumerable接口GetEnumerator()方法。迭代器匿名方法和第6頁Program2<T>類包含一個字段:stack。它類型為Stack(堆棧),并在該類結(jié)構(gòu)函數(shù)中初始化了stack字段。Program2<T>類還包含可兩個方法:Push(Titem)和Pop()。Push(Titem)方法將item元素壓入到stack堆棧中,Pop()方法彈出stack堆棧頂部元素。Program2<T>類實現(xiàn)了IEnumerable和IEnumerable<T>接口GetEnumerator()方法,詳細(xì)說明以下:publicIEnumerator<T>GetEnumerator()實現(xiàn)了IEnumerable<T>接口GetEnumerator()方法,它在while語句中使用yieldreturn語句產(chǎn)生迭代器元素。這些元素為stack堆棧中元素。IEnumeratorIEnumerable.GetEnumerator()方法實現(xiàn)了IEnumerable接口Get-Enumerator()方法,它調(diào)用上述方法實現(xiàn)。注意:和Program類一樣,Program2<T>類也是可枚舉類型。所以,能夠使用foreach語句遍歷Program2<T>類型實例。迭代器匿名方法和第7頁17.1.3使用IEnumerator和IEnumerator<T>接口為了創(chuàng)建類對象能夠在foreach循環(huán)中使用,必須實現(xiàn)IEnumerable和IEnumerator接口泛型或非泛型形式。這些接口都非常簡單,所以很輕易實現(xiàn)。本節(jié)我們來學(xué)習(xí)IEnumerator和IEnumerator<T>接口。IEnumerator表示枚舉器非泛型接口,支持對非泛型集合簡單迭代。IEnumerator<T>表示枚舉器泛型接口,支持泛型集合簡單迭代。迭代器匿名方法和第8頁1.IEnumerator接口foreach語句使用IEnumerator接口方法和屬性,迭代集合中全部元素。IEnumerator是全部非泛型枚舉數(shù)基接口,它包含2個方法和1個屬性,詳細(xì)說明以下所表示。MoveNext()方法:將枚舉數(shù)推進(jìn)到集合下一個元素,即將當(dāng)前指定元素指針指向集合中下一個元素。Reset()方法:重置枚舉數(shù),即把枚舉數(shù)設(shè)置位于集合中第一個元素之前。所以,該集合中下一個被訪問元素為集合第一個元素。Current屬性:獲取集合中當(dāng)前元素。注意:迭代器被創(chuàng)建之后,枚舉數(shù)定位在集合中第一個元素前。此時,Current屬性值為null。在調(diào)用Reset()方法后,枚舉數(shù)位于在集合第一個元素之前,首次調(diào)用MoveNext()方法會將枚舉數(shù)移到集合第一個元素。假如調(diào)用MoveNext()方法使得當(dāng)前指針超出了集合末尾,則將指針設(shè)置為該集合最終一個元素后面,并返回false。迭代器匿名方法和第9頁【示例17-3】下面首先創(chuàng)建Program類實例p,并獲取p實例迭代器,保留為ie。然后在while語句中使用MoveNext()方法和Current屬性依次顯示ie實例迭代器中每一個元素值。Programp

=newProgram();

//創(chuàng)建Program類實例IEnumerator

ie

=p.GetEnumerator();

//獲取p實例迭代器while(ie.MoveNext())

//移動到下一個元素,直到迭代器末尾{

Console.WriteLine(ie.Current);

//顯示迭代器當(dāng)前元素值}分析:在ie迭代器第一次調(diào)用MoveNext()方法之前,它Current屬性值為null。迭代器匿名方法和第10頁2.IEnumerator<T>接口IEnumerator<T>接口支持泛型集合簡單迭代,它包含3個方法和1個屬性,詳細(xì)說明以下所表示。MoveNext()方法:將枚舉數(shù)推進(jìn)到集合下一個元素,即將當(dāng)前指定元素指針指向集合中下一個元素。Reset()方法:重置枚舉數(shù),即把枚舉數(shù)設(shè)置位于集合中第一個元素之前。所以,該集合中下一個被訪問元素為集合第一個元素。Dispose()方法:釋放實例所占有資源。Current屬性:獲取集合中當(dāng)前元素。注意:IEnumerator<T>接口中MoveNext()方法、Reset()方法、Current屬性和IEnumerator接口相對應(yīng)方法和屬性意義相同。所以,在此不做詳細(xì)介紹。迭代器匿名方法和第11頁17.2使用

匿名方法匿名方法(anonymousmethod)是一個隱藏了名稱方法。它是創(chuàng)建與特定委托實例相關(guān)聯(lián)命名代碼塊一個方式。能夠經(jīng)過在代碼塊后面添加delegate關(guān)鍵字來創(chuàng)建匿名方法。本節(jié)我們來學(xué)習(xí)匿名方法。迭代器匿名方法和第12頁17.2.1創(chuàng)建匿名方法創(chuàng)建匿名方法方式和普通方法不一樣。匿名方法由delegate關(guān)鍵字、參數(shù)列表(可選)和包含在“{”和“}”分隔符中語句列表組成。從匿名方法組成元素能夠看到,匿名方法已經(jīng)省略了該方法名稱?!臼纠?7-4】下面向btnAdd(Button類實例)Click事件注冊了一個匿名方法。該匿名方法省略參數(shù)列表,并顯示“這是一個匿名方法?!薄tnAdd.Click+=delegate

//btnAdd是Button類實例,它包含Click事件{

Console.WriteLine("這是一個匿名方法。");}迭代器匿名方法和第13頁【示例17-5】下面代碼等效于示例17-4中代碼。btnAdd.Click+=new

EventHandler(AddClick);void

AddClick(objectsender,EventArgse){

Console.WriteLine("這是一個匿名方法。");}分析:上述程序代碼創(chuàng)建了AddClick(objectsender,EventArgse)方法,并經(jīng)過委托將該方法注冊到btnAdd(Button類實例)Click事件。示例17-4和示例17-5實現(xiàn)了一樣功效,不過示例17-5為方法提供了一個顯式命名。注意:在示例17-4中,發(fā)生了從匿名方法到EventHandler委托類型(Button類Click事件類型)隱式轉(zhuǎn)換。而且,只有當(dāng)委托參數(shù)列表和返回類型都必須與匿名方法兼容時,才能進(jìn)行從匿名方法到委托類型隱式轉(zhuǎn)換。迭代器匿名方法和第14頁【示例17-6】下面向btnAdd(Button類實例)Click事件注冊了一個匿名方法。該匿名方法包含了參數(shù)列表(包含2個參數(shù):sender和e),并顯示“這是一個匿名方法。”。btnAdd.Click+=delegate(objectsender,EventArgse)

//btnAdd是Button類實例,它包含Click事件{

Console.WriteLine("這是一個匿名方法。");}迭代器匿名方法和第15頁17.2.2將匿名方法作為參數(shù)傳遞因為匿名方法允許與委托關(guān)聯(lián)代碼以“內(nèi)聯(lián)”方式,所以能夠?qū)⒛涿椒ㄗ鳛榉椒▍?shù)來傳遞。【示例17-7】下面代碼實現(xiàn)以下3個功效。創(chuàng)建委托Weituo。該委托返回類型為int,并包含1個參數(shù):i,類型為int。創(chuàng)建int[]

Array(int[]array,Weituo

w)方法。該方法包含兩個參數(shù):array和w,array是一個元素類型為int數(shù)組,w類型為Weituo。該方法調(diào)用w委托方法對array數(shù)組上每一個元素進(jìn)行計算。最終,將計算結(jié)果作為該方法返回值。創(chuàng)建array數(shù)組,它包含5個元素(1、2、3、4和5)。最終調(diào)用Array

(int[]array,Weituo

w)方法對array數(shù)組進(jìn)行計算,計算結(jié)果保留為result數(shù)組。注意:在調(diào)用Array(int[]array,Weituo

w)方法時,將“delegate(inti){returni*

i;}”匿名方法作為參數(shù)來傳遞。該匿名方法用于計算i參數(shù)平方。迭代器匿名方法和第16頁delegateint

Weituo(inti);

//創(chuàng)建Weituo委托int[]

Array(int[]array,Weituow)//創(chuàng)建int[]

Array(int[]array,Weituo

w)方法{

int[]result=newint[][array.Length];

for(inti=0;i<result.Length;i++)

{

result[i]=w(array[i]);

//調(diào)用w委托方法對array數(shù)組上每一個元素進(jìn)行計算

}

returnresult;}int[]array={1,2,3,4,5};//調(diào)用Array(int[]array,Weituow)方法對array數(shù)組進(jìn)行計算int[]result=Array(array,delegate(inti){returni*

i;});迭代器匿名方法和第17頁17.3使用擴(kuò)展方法擴(kuò)展方法能夠使得開發(fā)人員能夠向現(xiàn)有類型“添加”新方法,使用時不需要去修改或編譯類型本身代碼。擴(kuò)展方法是一個靜態(tài)方法,能夠經(jīng)過擴(kuò)展類型實例來調(diào)用擴(kuò)展方法。迭代器匿名方法和第18頁17.3.1申明擴(kuò)展方法擴(kuò)展方法在使用之前也要申明。申明擴(kuò)展方法時,需要使用this修飾符。擴(kuò)展方法第一個參數(shù)指定該方法所作用類型,并使用this修飾符作為該參數(shù)前綴。注意:擴(kuò)展方法必須申明為靜態(tài)方法,且必須申明在靜態(tài)類中。迭代器匿名方法和第19頁【示例17-8】下面向Program靜態(tài)類添加一個擴(kuò)展方法:ToInt32(thisstringstr)。ToInt32

(thisstring

str)方法也為靜態(tài)方法,它能夠被string類型(由this修飾符指定)實例調(diào)用,并將字符串轉(zhuǎn)換為對應(yīng)整數(shù)。01

usingSystem;02

namespace示例chapter17//指定命名空間03

{04

publicstaticclassProgram//申明擴(kuò)展方法靜態(tài)類05

{06

publicstaticintToInt32(thisstringstr)07

//申明擴(kuò)展方法,并指定擴(kuò)展類型為string08

{09

returnInt32.Parse(str);10

}11

}12

}分析:ToInt32(thisstringstr)擴(kuò)展方法申明在“示例chapter17”命名空間Program靜態(tài)類中。迭代器匿名方法和第20頁【示例17-9】下面向Programs靜態(tài)類添加一個擴(kuò)展方法:ToInt32WithD

(thisstringstr,intd)。ToInt32WithD(thisstringstr,intd)方法也為靜態(tài)方法,它包含兩個參數(shù):str和d。str參數(shù)類型為string,被this修飾符修飾,所以,該擴(kuò)展方法能夠被string類型實例調(diào)用。d參數(shù)類型為int。ToInt32WithD(thisstringstr,intd)方法首先將str轉(zhuǎn)換為一個整數(shù),然后除以d參數(shù),并返回計算結(jié)果。01

usingSystem;02

namespace示例chapter17//指定命名空間03

{04

publicstaticclassProgram//申明擴(kuò)展方法靜態(tài)類05

{06

publicstaticintToInt32WithD(thisstringstr,intd)07

//申明擴(kuò)展方法,并指定擴(kuò)展類型為string08

{09

return(int)((double)Int32.Parse(str)/d);10

}11

}12

}分析:ToInt32WithD

(thisstringstr,intd)擴(kuò)展方法也被申明在“示例chapter17”命名空間Program靜態(tài)類中。迭代器匿名方法和第21頁普通情況下,不提議使用擴(kuò)展方法。在申明擴(kuò)展方法時,需要注意以下兩點。假如擴(kuò)展方法與其相關(guān)類型中定義方法含有相同署名,則擴(kuò)展方法永遠(yuǎn)不會被調(diào)用。擴(kuò)展方法屬于其所在命名空間。所以,假如使用using指令引入某一個命名空間,那么該命名空間中全部擴(kuò)展方法都將被導(dǎo)入。迭代器匿名方法和第22頁17.3.2導(dǎo)入擴(kuò)展方法導(dǎo)入擴(kuò)展方法比較簡單,只要使用using指令引入擴(kuò)展方法所在命名空間即可。實際上,被導(dǎo)入擴(kuò)展方法作為該方法第一個參數(shù)類型附加方法?!臼纠?7-10】下面使用using指令引入“示例chapter17”命名空間,同時也導(dǎo)入該命名空間中擴(kuò)展方法,如示例17-8中申明ToInt32

(thisstringstr)方法、示例17-9中申明T

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論