lambda表達式詳解


對於從來沒接觸過lambda表達式的人來說,這個玩意很蛋疼,蛋疼的語法,蛋疼的外表,但是就和人一樣,如果長得太突出(丑),一般就會有大才,畢竟老天是公平的嘛!

在具體分析lambda之前,先說兩句:

1.lambda表達式不是必須的,因為其就是一個匿名函數,凡是通過lambda表達式可以完成的工作,都可以通過匿名函數來完成(當然,我們也知道,匿名函數也不是必須的)。

2.lambda表達式可以極大簡化我們對匿名函數的使用.

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

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

通過上面的定義我們可以了解:

1.lambda表達式是匿名函數,只不過長得不太像而已,可以看成是進化版。

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的配合使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM