(轉(zhuǎn))C# Lambda表達(dá)式詳解曹洽,及Lambda表達(dá)式樹的創(chuàng)建

最近由于項(xiàng)目需要,剛剛學(xué)完了Action委托和Func<T>委托臊恋,發(fā)現(xiàn)學(xué)完了委托就必須學(xué)習(xí)lambda表達(dá)式衣洁,委托和Lambda表達(dá)式聯(lián)合起來,才能充分的體現(xiàn)委托的便利抖仅、才能使代碼更加簡介、優(yōu)雅砖第。

Lambda表達(dá)式

"Lambda表達(dá)式"是一個(gè)匿名函數(shù)撤卢,是一種高效的類似于函數(shù)式編程的表達(dá)式,Lambda簡化了開發(fā)中需要編寫的代碼量梧兼。它可以包含表達(dá)式和語句放吩,并且可用于創(chuàng)建委托或表達(dá)式目錄樹類型,支持帶有可綁定到委托或表達(dá)式樹的輸入?yún)?shù)的內(nèi)聯(lián)表達(dá)式羽杰。所有Lambda表達(dá)式都使用Lambda運(yùn)算符=>渡紫,該運(yùn)算符讀作"goes to"。Lambda運(yùn)算符的左邊是輸入?yún)?shù)(如果有)考赛,右邊是表達(dá)式或語句塊惕澎。Lambda表達(dá)式x => x * x讀作"x goes to x times x"⊙罩瑁可以將此表達(dá)式分配給委托類型唧喉,如下所示:

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

若要?jiǎng)?chuàng)建表達(dá)式目錄樹類型(后面會(huì)詳細(xì)說明):

using System.Linq.Expressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<del> myET = x => x * x;
        }
    }
}

1、表達(dá)式Lambda

表達(dá)式位于 => 運(yùn)算符右側(cè)的 lambda 表達(dá)式稱為“表達(dá)式 lambda”忍抽。 表達(dá)式 lambda 會(huì)返回表達(dá)式的結(jié)果八孝,并采用以下基本形式:

(input parameters) => expression

僅當(dāng) lambda 只有一個(gè)輸入?yún)?shù)時(shí),括號(hào)才是可選的鸠项;否則括號(hào)是必需的干跛。 括號(hào)內(nèi)的兩個(gè)或更多輸入?yún)?shù)使用逗號(hào)加以分隔:

(x, y) => x == y

有時(shí),編譯器難以或無法推斷輸入類型祟绊。 如果出現(xiàn)這種情況楼入,你可以按以下示例中所示方式顯式指定類型:

(int x, string s) => s.Length > x

使用空括號(hào)指定零個(gè)輸入?yún)?shù):

() => SomeMethod()

2、語句Lambda
當(dāng)lambda表達(dá)式中久免,有多個(gè)語句時(shí)浅辙,寫成如下形式:

(input parameters) => {statement;}

例如:

delegate void TestDelegate(string s);
…
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };
myDel("Hello");

看到這里,Lambda的基礎(chǔ)知識(shí)就學(xué)完了阎姥,下面來講解一下實(shí)際中是如何運(yùn)用的记舆,這里寫了幾個(gè)小例子:

            List<string> Citys= new List<string>()
            {
               "BeiJing",
               "ShangHai",
               "Tianjin",
               "GuangDong"
            };
            var result = Citys.First(c => c.Length > 7);

這個(gè)是大家熟悉的LINQ語句,如果沒學(xué)過沒關(guān)系呼巴,這里用的只是很簡單的幾個(gè)方法泽腮,相信大家都能看懂御蒲。

首先定義一個(gè)Citys集合,初始化有一些數(shù)據(jù)诊赊。然后調(diào)用LINQ的first方法厚满,查詢出來長度大于7的第一個(gè)結(jié)果,看到了吧碧磅,這里用的就是Lambda表達(dá)式碘箍,

如果我們自己寫,還要寫循環(huán)遍歷集合鲸郊,然后判斷字符串長度是否大于7丰榴,起碼要寫四五行代碼,而這里只要一行就夠了秆撮,而且LINQ也要寫很長四濒。

這里用的是最簡單的Lambda表達(dá)式,(input parameters) => expression的形式职辨。

下面來看一下盗蟆,如何自己定義和使用Lambda表達(dá)式,首先寫下面一個(gè)函數(shù):

    public void LambdaFun(string str,Func<string,string> func)
      {
         Console.WriteLine(func(str));
      }

這里用到了Func<T>委托舒裤,不懂的可以去百度查資料喳资,這個(gè)方法什么都沒有做,只是調(diào)用了委托方法惭每,并將參數(shù)傳遞過去骨饿,下面來看一下使用方法:

        LambdaFun("BeiJing 2013", s => 
         {
            if (s.Contains("2013"))
            {
               s = s.Replace("2013", "2014");
            }
            return s;
         });

這里將傳入字符串中的2013替換成為2014,當(dāng)然還可以是將其他字符串替換城任何內(nèi)容台腥,或者是截取宏赘,連接等等,完全由我們傳入的Lambda表達(dá)式?jīng)Q定黎侈,到了這里感覺到Lambda表達(dá)式的強(qiáng)大了吧察署。

**lambda表達(dá)式樹動(dòng)態(tài)創(chuàng)建方法 **

        static void Main(string[] args)
        {
            //i*j+w*x
            ParameterExpression a = Expression.Parameter(typeof(int),"i");   //創(chuàng)建一個(gè)表達(dá)式樹中的參數(shù),作為一個(gè)節(jié)點(diǎn)峻汉,這里是最下層的節(jié)點(diǎn)
            ParameterExpression b = Expression.Parameter(typeof(int),"j");
            BinaryExpression r1 = Expression.Multiply(a,b);    //這里i*j,生成表達(dá)式樹中的一個(gè)節(jié)點(diǎn)贴汪,比上面節(jié)點(diǎn)高一級(jí)

            ParameterExpression c = Expression.Parameter(typeof(int), "w");
            ParameterExpression d = Expression.Parameter(typeof(int), "x");
            BinaryExpression r2 = Expression.Multiply(c, d);

            BinaryExpression result = Expression.Add(r1,r2);   //運(yùn)算兩個(gè)中級(jí)節(jié)點(diǎn),產(chǎn)生終結(jié)點(diǎn)

            Expression<Func<int, int, int, int, int>> lambda = Expression.Lambda<Func<int, int, int, int, int>>(result,a,b,c,d);

            Console.WriteLine(lambda + "");   //輸出‘(i,j,w,x)=>((i*j)+(w*x))’休吠,z對應(yīng)參數(shù)b扳埂,p對應(yīng)參數(shù)a

            Func<int, int, int, int, int> f= lambda.Compile();  //將表達(dá)式樹描述的lambda表達(dá)式,編譯為可執(zhí)行代碼瘤礁,并生成該lambda表達(dá)式的委托阳懂;

            Console.WriteLine(f(1, 1, 1, 1) + "");  //輸出結(jié)果2
            Console.ReadKey();
        }

為了便于大家理解,這點(diǎn)代碼構(gòu)成的Lambda表達(dá)式樹如下圖:


image

其實(shí)Lambda表達(dá)式并不難,只有理解了其中的原理岩调,還是很快可以上手的巷燥!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市号枕,隨后出現(xiàn)的幾起案子缰揪,更是在濱河造成了極大的恐慌,老刑警劉巖葱淳,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钝腺,死亡現(xiàn)場離奇詭異,居然都是意外死亡赞厕,警方通過查閱死者的電腦和手機(jī)拍屑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坑傅,“玉大人,你說我怎么就攤上這事喷斋⊙涠荆” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵星爪,是天一觀的道長浆西。 經(jīng)常有香客問我,道長顽腾,這世上最難降的妖魔是什么近零? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮抄肖,結(jié)果婚禮上久信,老公的妹妹穿的比我還像新娘。我一直安慰自己漓摩,他們只是感情好裙士,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著管毙,像睡著了一般腿椎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夭咬,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天啃炸,我揣著相機(jī)與錄音,去河邊找鬼卓舵。 笑死南用,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播训枢,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼托修,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恒界?” 一聲冷哼從身側(cè)響起睦刃,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎十酣,沒想到半個(gè)月后涩拙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耸采,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年兴泥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虾宇。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搓彻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嘱朽,到底是詐尸還是另有隱情旭贬,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布搪泳,位于F島的核電站稀轨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岸军。R本人自食惡果不足惜奋刽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艰赞。 院中可真熱鬧佣谐,春花似錦、人聲如沸猖毫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吁断。三九已至趁蕊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仔役,已是汗流浹背掷伙。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留又兵,地道東北人任柜。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓卒废,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宙地。 傳聞我的和親對象是個(gè)殘疾皇子摔认,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容