lambda表達式詳解

對於歷來沒接觸過lambda表達式的人來講,這個玩意很蛋疼,蛋疼的語法,蛋疼的外表,可是就和人同樣,若是長得太突出(醜),通常就會有大才,畢竟老天是公平的嘛!函數

在具體分析lambda以前,先說兩句:學習

1.lambda表達式不是必須的,由於其就是一個匿名函數,凡是經過lambda表達式能夠完成的工做,均可以經過匿名函數來完成(固然,咱們也知道,匿名函數也不是必須的)。blog

2.lambda表達式能夠極大簡化咱們對匿名函數的使用.get

3.學習lambda表達式以前你最好對匿名函數、委託、泛型的概念有所瞭解。string

MSDN定義:Lambda 表達式是一種可用於建立委託表達式目錄樹類型的匿名函數it

經過上面的定義咱們能夠了解:編譯

1.lambda表達式是匿名函數,只不過長得不太像而已,能夠當作是進化版。class

2.lambda表達式是用來建立委託或者目錄樹的匿名函數匿名函數

目錄樹是何許人也,放到其餘章節說,這裏只說lambda表達式建立委託。泛型

  首先,建立一個委託

delegate int del(int arg);

  而後建立一個符合這個委託定義的方法

static int Func1(int numb)
        {
            return numb + 10;
        }

  建立委託del的實例,這裏建立委託的方法咱們用的是最基本的方法。

static void Main(string[] args)
        {
            del d1 = new del(Func1);
            Console.WriteLine(d1(10));
            Console.ReadKey();
        }

  好,上面咱們建立了委託del的實例。

咱們知道若是一個方法可能只用一次,咱們就不必單首創建這個方法,而是可使用匿名函數。那麼咱們假設Func就是那個只使用一次的函數,咱們能夠將上面的建立委託的實例的代碼改成使用匿名函數的版本。

 static void Main(string[] args)
        {
            del d1 = delegate(int numb)
            {
                return numb + 10;
            };
            Console.WriteLine(d1(10));
            Console.ReadKey();
        }

  分析一下這個匿名函數:delegaet關鍵字、匿名函數的參數的類型和形參名稱、函數體,還能不能更簡單一點呢?繼續看,主角來了

 static void Main(string[] args)
        {
            del d1 = p => p + 10;
            Console.WriteLine(d1(10));
            Console.ReadKey();
        }

  p=>p+10就是lambda表達式,咱們來分析一下,很簡單的喲

1.=>讀做「成爲」、"轉成",英文讀做"goes to"

2.=>左邊的p表示調用方法時給方法傳入的參數

3.=>右邊的p+10,表示方法體

對比上面使用匿名函數建立委託實例,左邊的p就至關於 numb,右邊的p+10就至關於{return p+10;}

咱們能夠樂觀的認爲,lambda表達式在編譯階段仍然轉換成了對應的匿名函數,別問我怎麼知道,我猜的!

畫張圖表示一下。

因此咱們前面說過,lambda表達式也是匿名函數,只不過簡化了匿名函數的使用。

因此咱們前面也說,lambda表達式是用來建立委託的,你看咱們剛纔不就是再建立委託的實例嗎?!

因此到如今爲止,你應該記住一句話:lamb表達式沒什麼特殊之處,只不過是C#的一種語言特性而已,或者說一種語法而已。

道理明白了,下面咱們來稍微增強一點。

定義一個兩個參數的委託

delegate int del(int arg1,int arg2);

  本身試試,首先使用匿名函數的方式建立這個委託的一個實例,而後再使用lambda表達式看看。

  使用匿名函數

del d1 = delegate(int numb1, int numb2)
            {
                return numb1 + numb2;
            };
            Console.WriteLine(d1(10,10));
            Console.ReadKey();

  使用lambda表達式

 del d1 = (p, z) => p + z;
            Console.WriteLine(d1(10,10));
            Console.ReadKey();

  沒錯,兩個參數的時候就是使用括號括起來,用都好分割兩個參數,這裏p就表示numb1,z就表示numb2。

咱們稍微弄個複雜點的:定義一個購物的委託

/// <summary>
        /// 定義一個購物的委託,分別接受兩個參數
        /// </summary>
        /// <param name="spend">實際消費金額</param>
        /// <param name="cash">付給商家的金額</param>
        /// <returns>商家找回的金額</returns>
        delegate double ShoppingDelegate(double spend, double cash);

  使用匿名方法的方式建立這個委託的實例,方法的邏輯稍微複雜點

ShoppingDelegate d1 = delegate(double spend, double cash)
            {
                /*變量card表示會員卡上的金額,咱們都有經驗,若是常常會將幾毛錢存入會員卡,方便下次使用,這樣能夠少帶零錢。若是會員卡的金額>0.5,則將會使用會員卡上的金額;不然不適用*/
                double card = 0.5;
                if (card > 3)
                {
                    return cash - spend + card;
                }
                else 
                {
                    return cash - spend;
                }
            };

  這樣該如何改爲lambda表達式呢?沒錯,若是代碼比較多的話,lambda表達式也使用{}。

ShoppingDelegate d1 = (p,z)=>
            {
                /*變量card表示會員卡上的金額,咱們都有經驗,若是常常會將幾毛錢存入會員卡,方便下次使用,這樣能夠少帶零錢。若是會員卡的金額>0.5,則將會使用會員卡上的金額;不然不適用*/
                double card = 0.5;
                if (card > 3)
                {
                    return z - p + card;
                }
                else 
                {
                    return z - p;
                }
            };

  有人會問,爲何lambda表達式中的參數p和z不用spend和cash表示呢?固然能夠了,只不過lambda表達式比較叼,能用一個字符表示的,絕對不使用一個半。

好,這一節就到這裏,下一節專門說說lambda表達式和linq的配合使用。

相關文章
相關標籤/搜索