http://javenstudio.org - C++ Java 分布式 搜索引擎 Naven's Research Laboratory - Thinking of Life, Imagination of Future
Lambda表達(dá)式是查詢體系(query architecture)的一個(gè)重要部分,擴(kuò)展方法(Extension methods)是另一個(gè)重要組成部分。擴(kuò)展方法結(jié)合了“duck typing”(一種可替代任何類(lèi)型的類(lèi)型)的彈性(flexibility)特點(diǎn),使得動(dòng)態(tài)語(yǔ)言(dynamic languages,如JavaScript)更加流行(popular),同時(shí)又有靜態(tài)型語(yǔ)言(statically typed languages,如C++和Java)的優(yōu)秀性能(performance)和編譯時(shí)驗(yàn)證(compile-time validation)的特點(diǎn)。通過(guò)擴(kuò)展方法,第三方(third parties)可以增加使用了新方法的類(lèi)型(type with new methods)的公共合同(public contract),使得獨(dú)立型的開(kāi)發(fā)者(individual type authors)還能提供他們對(duì)這些方法的自己專(zhuān)門(mén)的實(shí)現(xiàn)(specialized implementation)。
擴(kuò)展方法定義在靜態(tài)類(lèi)(static classes)里,就像靜態(tài)方法(static methods)一樣,但是它們?cè)?/SPAN>CLR元數(shù)據(jù)(CLR metadata)里卻被標(biāo)記為[System.Runtime.CompilerServices.Extension]。程序語(yǔ)言都被鼓勵(lì)(encourage)為擴(kuò)展方法提供一種直觀的語(yǔ)法(direct syntax)。在 C# 語(yǔ)言里,擴(kuò)展方法是由 this 指針(this modifer)標(biāo)示(indicate)的,它必須應(yīng)用于(applied to)擴(kuò)展方法的第一個(gè)參數(shù)。下面讓我們來(lái)看看一段最簡(jiǎn)單的查詢操作符(query operator)的定義代碼:
擴(kuò)展方法的第一個(gè)參數(shù)的類(lèi)型標(biāo)示(indicate)擴(kuò)展的內(nèi)容所應(yīng)用(the extension applies to)的類(lèi)型。在上面的例子中,擴(kuò)展方法 Where 擴(kuò)展自 IEnumerable<T> 類(lèi)型。因?yàn)?/SPAN> Where 是一個(gè)靜態(tài)方法(static method),所以我們可以像其他靜態(tài)方法一樣直接調(diào)用它(invoke it directly):
然而,擴(kuò)展方法的一個(gè)獨(dú)特(unique)的特點(diǎn)是我們還可以使用實(shí)例的語(yǔ)法(using instance syntax)來(lái)調(diào)用它:
擴(kuò)展方法是基于擴(kuò)展方法的活動(dòng)范圍內(nèi)(in scope)在編譯時(shí)(compile-time)決定的(resolved)。當(dāng)引入(import)一個(gè)命名空間(namespace)時(shí)(在 C# 里使用 using 語(yǔ)句,在VB 里使用 Import 語(yǔ)句),所有的擴(kuò)展方法是由從 namespace 帶入活動(dòng)范圍(brought into scope)的靜態(tài)類(lèi)(static classes)定義的。
標(biāo)準(zhǔn)查詢操作符(standard query operators)在 System.Query.Sequence 類(lèi)型里定義成擴(kuò)展方法。當(dāng)檢查標(biāo)準(zhǔn)查詢操作符時(shí),你將注意到它們中所有的方法根據(jù)(in terms of)接口IEnumerable<T> 來(lái)定義的(除了 OfType,將在后面介紹它)。這意味著每一個(gè)兼容 IEnumerable<T> 接口的信息源(information source)在 C# 語(yǔ)言里通過(guò)簡(jiǎn)單地添加如下的 using 語(yǔ)句就可以獲取標(biāo)準(zhǔn)查詢操作符:
用戶如果想用一個(gè)指定的類(lèi)型(specific type)來(lái)替換標(biāo)準(zhǔn)查詢操作符,可以在有一致標(biāo)識(shí)(compatible signatures)的指定的類(lèi)型上定義他們自己的相同名字的方法(same-named methods),另一種方法是通過(guò)擴(kuò)展指定的類(lèi)型來(lái)(extend the specific type)定義相同名字的方法。用戶如果想完全避免(eschew)使用標(biāo)準(zhǔn)查詢操作符,可以簡(jiǎn)單地將 System.Query 置于活動(dòng)范圍之外,并且為 IEnumerable<T> 接口寫(xiě)出他們自己的擴(kuò)展方法就可以了。
按照分析規(guī)則,擴(kuò)展方法被賦予了最低優(yōu)先權(quán)(lowest priority),它們只是在沒(méi)有相適配(suitable)的目標(biāo)類(lèi)型(target type)和它們的基類(lèi)型(base types)時(shí)才被使用。這個(gè)規(guī)則允許用戶自定的類(lèi)型(user-defined types)提供他們自己的查詢操作符,比標(biāo)準(zhǔn)查詢操作符更優(yōu)先使用(take precedence over)。例如,考慮用戶自定義 collection 的實(shí)現(xiàn)如下:
通過(guò)給出這個(gè)類(lèi)的定義,下面的程序:
將使用 MySequence.Where 的實(shí)現(xiàn),而不是擴(kuò)展方法,因?yàn)轭?lèi)實(shí)體方法(instance methods)比擴(kuò)展方法(extension methods)更優(yōu)先使用。
前面的提及(mentioned earlier)了屬于標(biāo)準(zhǔn)操作符(standard operator)一員但不是擴(kuò)展自基于IEnumerable<T> 接口(IEnumerable<T>-based)的信息源的 OfType 類(lèi)型,下面讓我們來(lái)看看 OfTyoe 查詢操作符:
OfType 即接受基于IEnumerable<T> 接口的信息源,也接受那些在 .NET Framework 1.0 中出現(xiàn)的非參數(shù)化的 IEnumerable 接口(non-parameterized IEnumerable interface)。OfType 操作符允許用戶在標(biāo)準(zhǔn)的 .NET collections 類(lèi)(classic .NET collections)上應(yīng)用標(biāo)準(zhǔn)查詢操作符,就像下面的程序:
在這個(gè)例子中,變量 modern 產(chǎn)生了與變量 classic 一樣的順序的數(shù)據(jù)列表(same sequence of values),但是不同的是它的類(lèi)型兼容最新的 IEnumerable<T> 代碼(modern IEnumerable<T> code),包括標(biāo)準(zhǔn)查詢操作符。
OfType 操作符對(duì)新的信息源也是有用的,因?yàn)樗试S從基于類(lèi)型的信息源(source based on type)中過(guò)濾出數(shù)據(jù)(filtering values from)。當(dāng)要制作新的順序的時(shí)候(producing the new sequence),OfType 簡(jiǎn)單的忽略(omits)原有序列的成員(members of the original sequence)就可以了,這是與類(lèi)型實(shí)參(type argument)不相符的。分析下面的程序,目標(biāo)是將 string 字符串?dāng)?shù)據(jù)從一個(gè)有不同種類(lèi)數(shù)據(jù)的數(shù)組(heterogeneous array)中分解出來(lái):
當(dāng)在 foreach 語(yǔ)句中列舉(enumerate)變量 justStrings 中的數(shù)據(jù)時(shí),將得到兩個(gè)依次為“Hello”和“World”的 string 字符串序列(a sequence of two strings )。
待續(xù), 錯(cuò)誤難免,請(qǐng)批評(píng)指正,譯者Naven 2005-10-22
Powered by: C++博客 Copyright © Javen-Studio