中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

lambda表達(dá)式之進(jìn)化

前言

在C#我們可以自定義委托,但是C#為什么還要內(nèi)置泛型委托呢?因?yàn)槲覀兂3R褂梦?,如果系統(tǒng)內(nèi)置了一些你可能會(huì)用到的委托,那么就省去了定義委托,然后實(shí)例化委托的步驟,這樣一來(lái)既使代碼看起來(lái)簡(jiǎn)潔而干凈又能提高程序員的開(kāi)發(fā)速度,何樂(lè)不為呢!通過(guò)本文可以讓你復(fù)習(xí)擴(kuò)展方法,同時(shí)可以循序漸進(jìn)的了解系統(tǒng)內(nèi)置泛型委托的實(shí)現(xiàn)以及委托逐步的演化過(guò)程。

成都創(chuàng)新互聯(lián)專(zhuān)注于咸陽(yáng)企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站設(shè)計(jì),電子商務(wù)商城網(wǎng)站建設(shè)。咸陽(yáng)網(wǎng)站建設(shè)公司,為咸陽(yáng)等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

 Action

概念:封裝一個(gè)方法,該方法具有五個(gè)參數(shù)并且不返回值。并且類(lèi)型參數(shù)為逆變

下面我就自定義實(shí)現(xiàn)一個(gè)Action<T>無(wú)返回值的委托。我們同樣定義一個(gè)Person類(lèi),似乎我隨筆中永遠(yuǎn)都離不開(kāi)Person的話(huà)題,哈哈!請(qǐng)看如下代碼

 lambda表達(dá)式之進(jìn)化

    public class Person
    {        public string Name { get; set; }        public int Age { get; set; }        public bool Gender { get; set; }
    }

 lambda表達(dá)式之進(jìn)化

然后在控制臺(tái)中通過(guò) ForEach 方法模擬Action委托,先定義一個(gè)獲得Person的列表GetList()

 lambda表達(dá)式之進(jìn)化

        static List<Person> GetList()
        {
            List<Person> list = new List<Person>() { 
            new Person(){ Name = "花千骨     (女?huà)z后人及妖神)",   Age = 12, Gender = false},            new Person(){ Name = "白子畫(huà)     (長(zhǎng)留尊上)",   Age = 13, Gender = true},            new Person(){ Name = "東方彧卿   (異朽閣主及蜀國(guó)大學(xué)士)", Age = 14, Gender = true},            new Person(){ Name = "輕水       (長(zhǎng)留弟子)",     Age = 15, Gender = false},            new Person(){ Name = "孟玄朗     (蜀國(guó)皇帝及長(zhǎng)留弟子)",   Age = 16, Gender = true}
            };            return list;
        }

 lambda表達(dá)式之進(jìn)化

因?yàn)槲覀冎涝谟梦袝r(shí),有這樣幾個(gè)步驟:

(1)定義委托

(2)實(shí)例化委托

(3)將方法指針添加到實(shí)例化委托對(duì)象中

 但是現(xiàn)在我們無(wú)需定義委托,已經(jīng)有了內(nèi)置委托,只需將其實(shí)例化即可,同時(shí)添加方法的指針一般是有明確的方法,如果我們只是臨時(shí)的用方法,這時(shí)就可以派匿名方法上場(chǎng)了,所以上面三步就可以簡(jiǎn)化成兩步。代碼如下:

 lambda表達(dá)式之進(jìn)化

            var list = GetList();

            list.ForEach(new Action<Person>
                (                  delegate(Person p)
                  {
                      Console.WriteLine(p.Name);
                  }
                ));

 lambda表達(dá)式之進(jìn)化

上述代碼頗有點(diǎn)jQuery中Each的遍歷方法的意味。結(jié)果打印出:

 lambda表達(dá)式之進(jìn)化

 我們知道ForEach這個(gè)方法里面的的參數(shù)就是 Action<T> action ,所以我們可以直接進(jìn)行如下簡(jiǎn)寫(xiě)

 list.ForEach(delegate(Person p) { Console.WriteLine(p.Name); });

其打印結(jié)果和上面是一樣的。其代碼可以繼續(xù)進(jìn)行更加的精簡(jiǎn),不著急,我們循序漸進(jìn)的來(lái)。

Predicate

概念:定義一組條件并確定指定對(duì)象是否符合這些條件的方法。返回值為bool類(lèi)型,并且類(lèi)型參數(shù)為逆變。

用到此泛型委托莫過(guò)于List中的 FindAll() 方法了,它就是從一個(gè)集合中根據(jù)條件篩選出一個(gè)新的集合出來(lái)。上節(jié)剛好學(xué)過(guò)擴(kuò)展方法,我們可以自定義實(shí)現(xiàn)這個(gè)方法用擴(kuò)展方法加在泛型集合List上根據(jù)  Predicate 委托的參數(shù)條件進(jìn)行篩選。

 lambda表達(dá)式之進(jìn)化

static List<T> SelfDefineFindAll<T> (this List<T> list, Predicate<T> pre)   /*注意:既然是添加的擴(kuò)展方法,在此例中控制臺(tái)的Program也要聲明為靜態(tài)類(lèi)*/{
      List<T> preList = new List<T>; /*根據(jù)條件篩選出的數(shù)據(jù)添加到該集合中*/    
      foreach (T t in list)
     {            if (pre(t)) /*根據(jù)條件進(jìn)行篩選*/
            {
                preList.Add(t);
            }
     }      return preList;
}

 lambda表達(dá)式之進(jìn)化

我們查詢(xún)出年紀(jì)大于13歲的并且根據(jù)ForEach來(lái)遍歷篩選出來(lái)的數(shù)據(jù),代碼如下:

 var list = GetList(); var preList = list.SelfDefineFindAll(delegate(Person p) { return p.Age > 13; });

 preList.ForEach(delegate(Person p) { Console.WriteLine(p.Name); });

結(jié)果打印出正確的結(jié)果,如下:

 lambda表達(dá)式之進(jìn)化

而通過(guò)C#中的FindAll,則只需如下做即可同樣達(dá)到上述的效果,只是不是擴(kuò)展方法罷了: 

list.FindAll(delegate(Person p) { return p.Name});

上述代碼其實(shí)可以更加精簡(jiǎn),不著急,我們一步一步循序漸進(jìn)的來(lái)。 

Comparison

概念:表示比較同一類(lèi)型的兩個(gè)對(duì)象的方法。參數(shù)類(lèi)型為逆變,返回值為int。

 list.Sort(new Comparison<Person>(delegate(Person p, Person p1) { return p.Age - p1.Age; }));  /*年齡按照從小到大順序排列*/

同樣可以簡(jiǎn)寫(xiě)為:

 list.Sort((delegate(Person p, Person p1) { return p.Age - p1.Age; }));

Func

貌似在系統(tǒng)內(nèi)置泛型委托中Func在實(shí)際項(xiàng)目開(kāi)發(fā)中是使用的最多的。

概念:封裝一個(gè)具有一個(gè)參數(shù)并返回 TResult 參數(shù)指定的類(lèi)型值的方法。參數(shù)類(lèi)型為逆變,返回值參數(shù)類(lèi)型為協(xié)變。

用到此委托的最多的就是List泛型集合中的 Select 方法了,看看內(nèi)置的Select方法是如何利用Func來(lái)實(shí)現(xiàn)返回一個(gè)新的集合的。

(1)結(jié)合匿名方法實(shí)現(xiàn)

我們接下來(lái)在上面基礎(chǔ)上再定義一個(gè)Animal類(lèi)。屬性和Person類(lèi)一樣,代碼如下:

 lambda表達(dá)式之進(jìn)化

    public class Animal
    {        public string Name { get; set; }        public int Age { get; set; }        public bool Gender { get; set; }
    }

 lambda表達(dá)式之進(jìn)化

接下來(lái)我們就通過(guò)Select方法通過(guò)Person的集合來(lái)返回一個(gè)新的集合即Animal集合。代碼如下:

 lambda表達(dá)式之進(jìn)化

            var list = GetList();

            List<Animal> animalList = list.Select(new Func<Person, Animal>(delegate(Person p)
            {                return new Animal() { Name = p.Name, Age = p.Age, Gender = p.Gender };
            })).ToList();

            animalList.ForEach(delegate(Animal animal) { Console.WriteLine(animal.Name); });

 lambda表達(dá)式之進(jìn)化

同樣打印出當(dāng)遍歷Person集合時(shí)的結(jié)果一樣,看起來(lái)似乎很繁瑣,我們將代碼通過(guò)進(jìn)行精簡(jiǎn)如下:

 lambda表達(dá)式之進(jìn)化

            var list = GetList();

            List<Animal> animalList = list.Select((delegate(Person p)
            {                return new Animal() { Name = p.Name, Age = p.Age, Gender = p.Gender };
            })).ToList();

            animalList.ForEach(delegate(Animal animal) { Console.WriteLine(animal.Name); });

 lambda表達(dá)式之進(jìn)化

下面我們通過(guò)擴(kuò)展方法來(lái)自定義實(shí)現(xiàn)Select()方法,代碼如下:

 lambda表達(dá)式之進(jìn)化

        public static List<TR> SelfDefineSelect<T, TR>(this List<T> list, Func<T, TR> fun)/*T為傳進(jìn)來(lái)的泛型集合類(lèi)型,TR為返回的泛型集合類(lèi)型*/
        {
            List<TR> selList = new List<TR>();  /*實(shí)例化返回的泛型集合*/            foreach (T t in list)
            {
                TR tr = fun(t);  /*獲取傳進(jìn)來(lái)的集合數(shù)據(jù)*/
                selList.Add(tr);
            }            return selList;  /*返回新的泛型集合*/
        }

 lambda表達(dá)式之進(jìn)化

 依然是進(jìn)行此調(diào)用,打印結(jié)果正確:

            List<Animal> animalList = list.SelfDefineSelect((delegate(Person p)
            {                return new Animal() { Name = p.Name, Age = p.Age, Gender = p.Gender };
            })).ToList();

 (2)結(jié)合匿名類(lèi)來(lái)實(shí)現(xiàn)

當(dāng)我們使用Func根據(jù)條件轉(zhuǎn)換成新的集合時(shí)可能只需要幾個(gè)實(shí)例成員,這個(gè)時(shí)候如果還重新建立一個(gè)類(lèi)來(lái)進(jìn)行獲取就顯得有點(diǎn)小題大做了,這個(gè)時(shí)候只需將其需要的或的成員傳給一個(gè)匿名類(lèi)即可,這個(gè)就是Func需要用到匿名類(lèi)的場(chǎng)景。所以鑒于此,我們將返回的新的集合為匿名集合而非Animal集合,代碼改造如下:

            var anyousList = list.Select((delegate(Person p)
            {                return new { Name = p.Name}; /*結(jié)合匿名類(lèi)使用*/
            }));

通過(guò)上述所講系統(tǒng)內(nèi)置泛型委托的實(shí)現(xiàn),似乎有點(diǎn)不太令人滿(mǎn)意,關(guān)于委托的代碼太過(guò)繁瑣,是的微軟大大也明確知道了這點(diǎn),于是乎,一步一步走向了高級(jí),那就下文的lambda表達(dá)式,這結(jié)構(gòu)的簡(jiǎn)單簡(jiǎn)直了。。。讓你爽到暴。

lambda表達(dá)式

 上述代碼說(shuō)過(guò)可以精簡(jiǎn),如何精簡(jiǎn)呢?那就是lambda表達(dá)式,匿名方法已經(jīng)夠簡(jiǎn)潔的了,但是lambda表達(dá)式是比匿名方法更加簡(jiǎn)潔的一種語(yǔ)法!我們用lambda表達(dá)式來(lái)分別實(shí)現(xiàn)上述中的Action、Predicate以及Func委托。

Action

            var list = GetList();

            list.ForEach(d => Console.WriteLine(d.Name);)

Predicate

            var list = GetList();

            list.FindAll(d => d.Age > 13);

Func

            list.Select(d =>  Person() { Name = d.Name, Age = d.Age, Gender ==>  { Name = d.Name});

好了,一切都變得如此明朗。自從有了lambda表達(dá)式,敲代碼的速度加快了,媽媽再也不用擔(dān)心我熬夜到很晚了。 

好了,問(wèn)題來(lái)了,我們知道lambda表達(dá)式分為 語(yǔ)句lambda和表達(dá)式lambda  ,那么二者有何區(qū)別呢?從字面上理解語(yǔ)句lambda是不是就是用大括號(hào)括起來(lái)的呢?ok,給出代碼來(lái)理解吧。

(string str) => { return str.length; }  /*語(yǔ)句lambda(有大括號(hào)和return)*/(string str) => str.length  /*表達(dá)式lambda(沒(méi)有大括號(hào)和return,只有一個(gè)式子)*/

那問(wèn)題又來(lái)了,lambda表達(dá)式到底是什么呢?我們依然用反編譯來(lái)查看  list.ForEach(d => Console.WriteLine(d.Age)); 對(duì)應(yīng)的C#代碼如下:

 lambda表達(dá)式之進(jìn)化

 看ForEach()方法里面的參數(shù)意思大概是匿名方法委托,接著我們點(diǎn)擊進(jìn)去看看,代碼如下:

 lambda表達(dá)式之進(jìn)化

我們接著點(diǎn)擊Action看看,如下:

 lambda表達(dá)式之進(jìn)化

一下就豁然開(kāi)朗了,這不正說(shuō)明 lambda表達(dá)式的實(shí)質(zhì)就是匿名方法 嗎!所以現(xiàn)在想想,lambda表達(dá)式的本質(zhì)是匿名方法,匿名方法的本質(zhì)是通過(guò)委托實(shí)現(xiàn)的。應(yīng)該就是這樣了。

lambda表達(dá)式進(jìn)化過(guò)程 

我們就一個(gè)擴(kuò)展方法的實(shí)例來(lái)演示lambda表達(dá)式演變的過(guò)程是多么的惟妙惟肖。

假設(shè)如下場(chǎng)景:在花千骨電視中找出白子畫(huà)出來(lái),找對(duì)了你就贏了!我們獲得給出一個(gè)花千骨眾角色列表,再選出白子畫(huà)即可。

 lambda表達(dá)式之進(jìn)化

             /*根據(jù)條件找出所需,返回true你就贏了,反之則輸*/

             static bool SelDefine_Extension_IEnumerable<T>(this IEnumerable<T> source, Func<T, bool> func)
             {                 foreach (var item in source)
                 {                    if (func(item))
                    {                        return true;
                    }
                 }                 return false;
             }

 lambda表達(dá)式之進(jìn)化

下面給出集合列表:

            var list = new List<string>() { "花千骨", "白子畫(huà)", "東方彧卿", "霓漫天", "糖寶", "落十一", "輕水", "孟玄朗" };

然后在控制臺(tái)執(zhí)行擴(kuò)展方法進(jìn)行查詢(xún),在此列出 lambda表達(dá)式6部曲 :

 lambda表達(dá)式之進(jìn)化

            list.SelDefine_Extension_IEnumerable(

 lambda表達(dá)式之進(jìn)化

從開(kāi)始的繁瑣,復(fù)雜到最終的簡(jiǎn)潔,每一個(gè)過(guò)程微軟大大也是作出一定的努力,先點(diǎn)給贊先!就上述用一副圖來(lái)看,估計(jì)會(huì)更加清晰明了吧

lambda表達(dá)式演變六部曲

 lambda表達(dá)式之進(jìn)化

文章名稱(chēng):lambda表達(dá)式之進(jìn)化
文章URL:http://www.rwnh.cn/article22/jgpijc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、定制網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、動(dòng)態(tài)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開(kāi)發(fā)
凤翔县| 灵武市| 峡江县| 夏河县| 左贡县| 凤阳县| 浦城县| 东莞市| 越西县| 长治市| 额敏县| 临洮县| 山西省| 东阳市| 龙陵县| 周口市| 通许县| 阆中市| 弥勒县| 永年县| 丁青县| 延川县| 无棣县| 唐海县| 绵阳市| 万荣县| 和政县| 平定县| 石景山区| 卓尼县| 美姑县| 景谷| 军事| 封开县| 巴林左旗| 济阳县| 开平市| 九龙县| 刚察县| 蓝山县| 高尔夫|