• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Javen-Studio 咖啡小屋

            http://javenstudio.org - C++ Java 分布式 搜索引擎
            Naven's Research Laboratory - Thinking of Life, Imagination of Future

              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              24 隨筆 :: 57 文章 :: 170 評(píng)論 :: 4 Trackbacks

            3.2         擴(kuò)展方法(Extension Methods

            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)的定義代碼:

             

            namespace System.Query {
              
            using System;
              
            using System.Collections.Generic;

              
            public static class Sequence {
                
            public static IEnumerable<T> Where<T>(
                         
            this IEnumerable<T> source,
                              Func
            <T, bool> predicate) {

                  
            foreach (T item in source)
                    
            if (predicate(item))
                      yield 
            return item;
                }

              }

            }

             

            擴(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):

             

            IEnumerable<string> expr = Sequence.Where(names, 
                                                      s 
            => s.Length < 6);

             

            然而,擴(kuò)展方法的一個(gè)獨(dú)特(unique)的特點(diǎn)是我們還可以使用實(shí)例的語(yǔ)法(using instance syntax)來(lái)調(diào)用它:

             

            IEnumerable<string> expr = names.Where(s => s.Length < 6);

             

            擴(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)查詢操作符:

             

            using System.Query; // makes query operators visible

             

            用戶如果想用一個(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)如下:

             

            public class MySequence : IEnumerable<int> {
              
            public IEnumerator<int> GetEnumerator() {
                
            for (int i = 1; i <= 10; i++
                  yield 
            return i; 
              }


              IEnumerator IEnumerable.GetEnumerator() 
            {
                
            return GetEnumerator(); 
              }


              
            public IEnumerable<int> Where(Func<intbool> filter) {
                
            for (int i = 1; i <= 10; i++
                  
            if (filter(i)) 
                    yield 
            return i;
              }

            }

             

            通過(guò)給出這個(gè)類(lèi)的定義,下面的程序:

             

            MySequence s = new MySequence();
            foreach (int item in s.Where(n => n > 3))
                Console.WriteLine(item);

             

            將使用 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 查詢操作符:

             

            public static IEnumerable<T> OfType<T>(this IEnumerable source) {
              
            foreach (object item in source) 
                
            if (item is T) 
                  yield 
            return (T)item;
            }

             

            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)查詢操作符,就像下面的程序:

             

            // "classic" cannot be used directly with query operators
            IEnumerable classic = new OlderCollectionType();

            // "modern" can be used directly with query operators
            IEnumerable<object> modern = classic.OfType<object>();

             

            在這個(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):

             

            object[] vals = 1"Hello"true"World"9.1 };
            IEnumerable
            <string> justStrings = vals.OfType<string>();

             

            當(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

            posted on 2005-10-22 22:30 Javen-Studio 閱讀(1345) 評(píng)論(3)  編輯 收藏 引用

            評(píng)論

            # re: 擴(kuò)展方法(Extension Methods) 2008-01-16 17:38 蜜桃
            為什么留那么多沒(méi)有必要的原文,看的眼花繚亂?
            既然是翻譯,除了會(huì)引起歧義的,就沒(méi)有必要留那么多原文。  回復(fù)  更多評(píng)論
              

            # re: 擴(kuò)展方法(Extension Methods) 2008-01-16 17:43 Javen-Studio
            哦,為了方便對(duì)照著看,感覺(jué)這樣會(huì)看得更仔細(xì)些:)  回復(fù)  更多評(píng)論
              

            # re: 擴(kuò)展方法(Extension Methods) 2008-11-18 01:12 GUYUE
            看來(lái) mitao 對(duì)自己的英文翻譯很有把握啊...
            不過(guò),怎么不看見(jiàn)你也這么認(rèn)真仔細(xì)的翻譯這么好的文章呢??



            謝謝分享.萬(wàn)分感謝。  回復(fù)  更多評(píng)論
              


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            精品99久久aaa一级毛片| 亚洲精品乱码久久久久久中文字幕 | 久久婷婷五月综合97色一本一本| 看全色黄大色大片免费久久久| 亚洲国产精品成人久久蜜臀 | 国产成人久久精品区一区二区| 久久久久亚洲AV片无码下载蜜桃| 久久www免费人成精品香蕉| 久久无码AV中文出轨人妻| 蜜臀av性久久久久蜜臀aⅴ| 精品人妻伦一二三区久久| 久久久无码精品亚洲日韩京东传媒| 久久综合久久综合九色| 亚洲精品国产字幕久久不卡| 国产精品一区二区久久国产| 久久综合88熟人妻| 久久国产影院| 青青青国产成人久久111网站| 一级女性全黄久久生活片免费 | 伊人久久大香线焦AV综合影院| 人人狠狠综合88综合久久| 99久久精品国产毛片| 国内精品人妻无码久久久影院| 久久久久久亚洲精品不卡| 97久久超碰国产精品旧版| 99久久做夜夜爱天天做精品| 国产69精品久久久久9999APGF| 欧美精品一区二区精品久久| 久久久无码精品亚洲日韩按摩| 伊人久久一区二区三区无码| 久久久久亚洲AV成人网人人软件| 99精品久久久久久久婷婷| 亚洲欧美一区二区三区久久| 国产成人综合久久精品红| 一本伊大人香蕉久久网手机| av国内精品久久久久影院| 精品久久久久久无码专区不卡| 色妞色综合久久夜夜| 狠狠色丁香久久婷婷综合五月| 国内精品久久久久影院日本| 久久精品99久久香蕉国产色戒|