一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

lambda表達(dá)式之進化

 weijianian 2016-08-09


來源:xpy0928

鏈接:http://www.cnblogs.com/CreateMyself/p/4727220.html


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


 Action


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


下面我就自定義實現(xiàn)一個Action無返回值的委托。我們同樣定義一個Person類,似乎我隨筆中永遠(yuǎn)都離不開Person的話題,哈哈!請看如下代碼


 public class Person

    {

        public string Name { get; set; }

 

        public int Age { get; set; }

 

        public bool Gender { get; set; }

    }


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


static List GetList()

        {

            List list = new List() {

            new Person(){ Name = '花千骨     (女媧后人及妖神)',   Age = 12, Gender = false},

            new Person(){ Name = '白子畫     (長留尊上)',   Age = 13, Gender = true},

            new Person(){ Name = '東方彧卿   (異朽閣主及蜀國大學(xué)士)', Age = 14, Gender = true},

            new Person(){ Name = '輕水       (長留弟子)',     Age = 15, Gender = false},

            new Person(){ Name = '孟玄朗     (蜀國皇帝及長留弟子)',   Age = 16, Gender = true}

            };

 

            return list;

        }


因為我們知道在用委托時,有這樣幾個步驟:


(1)定義委托


(2)實例化委托


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


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


var list = GetList();

 

            list.ForEach(new Action

                (

                  delegate(Person p)

                  {

                      Console.WriteLine(p.Name);

                  }

                ));


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



我們知道ForEach這個方法里面的的參數(shù)就是 Action action ,所以我們可以直接進行如下簡寫


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


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


Predicate


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


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


static List SelfDefineFindAll (this List list, Predicate pre)   /*注意:既然是添加的擴展方法,在此例中控制臺的Program也要聲明為靜態(tài)類*/

{

      List preList = new List; /*根據(jù)條件篩選出的數(shù)據(jù)添加到該集合中*/

    

      foreach (T t in list)

     {

            if (pre(t)) /*根據(jù)條件進行篩選*/

            {

                preList.Add(t);

            }

     }

 

      return preList;

}


我們查詢出年紀(jì)大于13歲的并且根據(jù)ForEach來遍歷篩選出來的數(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é)果,如下:



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


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


上述代碼其實可以更加精簡,不著急,我們一步一步循序漸進的來。


Comparison


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


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


同樣可以簡寫為:


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


Func


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


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


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


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


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


public class Animal

    {

        public string Name { get; set; }

 

        public int Age { get; set; }

 

        public bool Gender { get; set; }

    }


接下來我們就通過Select方法通過Person的集合來返回一個新的集合即Animal集合。代碼如下:


var list = GetList();

 

            List animalList = list.Select(new Func(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); });


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


 var list = GetList();

 

            List 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); });


下面我們通過擴展方法來自定義實現(xiàn)Select()方法,代碼如下:


publicstatic ListSelfDefineSelect(this List list, Func fun)/*T為傳進來的泛型集合類型,TR為返回的泛型集合類型*/

        {

            List selList = new List();  /*實例化返回的泛型集合*/

            foreach (T t in list)

            {

                TR tr = fun(t);  /*獲取傳進來的集合數(shù)據(jù)*/

                selList.Add(tr);

            }

            return selList;  /*返回新的泛型集合*/

        }


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


 List animalList = list.SelfDefineSelect((delegate(Person p)

            {

                return new Animal() { Name = p.Name, Age = p.Age, Gender = p.Gender };

            })).ToList();


 (2)結(jié)合匿名類來實現(xiàn)


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


var anyousList = list.Select((delegate(Person p)

            {

                return new { Name = p.Name}; /*結(jié)合匿名類使用*/

            }));


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


lambda表達(dá)式


上述代碼說過可以精簡,如何精簡呢?那就是lambda表達(dá)式,匿名方法已經(jīng)夠簡潔的了,但是lambda表達(dá)式是比匿名方法更加簡潔的一種語法!我們用lambda表達(dá)式來分別實現(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 => new Person() { Name = d.Name, Age = d.Age, Gender = d.Gender });

 list.Select(d => new { Name = d.Name});  /*lambda表達(dá)式中的匿名類*/


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


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


(string str) => { return str.length; }  /*語句lambda(有大括號和return)*/

(string str) => str.length  /*表達(dá)式lambda(沒有大括號和return,只有一個式子)


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



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



我們接著點擊Action看看,如下:



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


lambda表達(dá)式進化過程


我們就一個擴展方法的實例來演示lambda表達(dá)式演變的過程是多么的惟妙惟肖。


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


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

 

             static bool SelDefine_Extension_IEnumerable(this IEnumerable source, Funcbool> func)

             {

                 foreach (var item in source)

                 {

                    if (func(item))

                    {

                        return true;

                    }

                 }

 

                 return false;

             }


下面給出集合列表:


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


然后在控制臺執(zhí)行擴展方法進行查詢,在此列出 lambda表達(dá)式6部曲 :


list.SelDefine_Extension_IEnumerable(new Func(delegate(string item) { return item.Equals('白子畫'); }));

            

            list.SelDefine_Extension_IEnumerable(delegate(string item) { return item.Equals('白子畫'); });

 

            list.SelDefine_Extension_IEnumerable((string item) => { return item.Equals('白子畫'); });

 

            list.SelDefine_Extension_IEnumerable((string item) => item.Equals('白子畫'));

 

            list.SelDefine_Extension_IEnumerable((item) => item.Equals('白子畫'));

 

            list.SelDefine_Extension_IEnumerable(item => item.Equals('白子畫'));


從開始的繁瑣,復(fù)雜到最終的簡潔,每一個過程微軟大大也是作出一定的努力,先點給贊先!就上述用一副圖來看,估計會更加清晰明了吧


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



    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产成人精品国内自产拍| 日本淫片一区二区三区| 亚洲欧美国产中文色妇| 亚洲妇女作爱一区二区三区| 亚洲国产黄色精品在线观看| 精品视频一区二区不卡| 久久精品国产亚洲熟女| 有坂深雪中文字幕亚洲中文| 国产在线视频好看不卡| 国产精品免费无遮挡不卡视频| 成人日韩在线播放视频| 亚洲精选91福利在线观看| 美女露小粉嫩91精品久久久| 国产成人亚洲欧美二区综| 99一级特黄色性生活片| 亚洲品质一区二区三区| 日本高清二区视频久二区| 国产精品亚洲二区三区| 国产无摭挡又爽又色又刺激| 99久久国产综合精品二区| 国产老熟女超碰一区二区三区| 91人妻久久精品一区二区三区| 丰满少妇被粗大猛烈进出视频| 粉嫩一区二区三区粉嫩视频| 东京热一二三区在线免| 婷婷一区二区三区四区| 又大又长又粗又黄国产| 91蜜臀精品一区二区三区| 欧美人妻少妇精品久久性色 | 日韩人妻一区中文字幕| 国产性情片一区二区三区| 中文人妻精品一区二区三区四区| 久久夜色精品国产高清不卡| 开心久久综合激情五月天| 真实国产乱子伦对白视频不卡| 黄片美女在线免费观看| 人妻乱近亲奸中文字幕| 日韩一区二区三区嘿嘿| 中文日韩精品视频在线| 五月婷婷欧美中文字幕| 日本午夜乱色视频在线观看|