C# Lambda表示式詳解,及Lambda表示式樹的建立

Nincems發表於2018-11-19

本文轉自:https://www.cnblogs.com/mq0036/p/7427892.html

在 2.0 之前的 C# 版本中,宣告委託的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表示式取代了匿名方法,作為編寫內聯程式碼的首選方式。 有一種情況下,匿名方法提供了 Lambda 表示式中所沒有的功能。 您可使用匿名方法來忽略引數列表。 這意味著匿名方法可轉換為具有各種簽名的委託。 這對於 Lambda 表示式來說是不可能的。 有關 lambda 表示式的更多特定資訊,請參見 Lambda 表示式(C# 程式設計指南)。

總結下紅色那段話的意思:微軟告訴你:我們在C#2.0之前就有委託了,在2.0之後又引入了匿名方法,C#3.0之後,又引入了Lambda表示式,他們三者之間的順序是:委託->匿名變數->Lambda表示式,微軟的一步步升級,帶給我們程式設計上的優美,簡潔,可讀性強.....在此,不多誇微軟,怕他們看到這篇部落格後驕傲,怕他們尾巴能翹到天上,不知天高地厚。嘿嘿,說多了!

溫故而知新,可以做老師,我們們來溫故下委託和匿名錶達式。

委託如下:

delegate int calculator(int x, int y); //委託型別
    static void Main()
    {
        calculator cal = new calculator(Adding);
        int He = cal(1, 1);
        Console.Write(He);
    }

    /// <summary>
    /// 加法
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public static int Adding(int x, int y)
    {
        return x + y;
    }

匿名方法如下:

delegate int calculator(int x, int y); //委託
    static void Main()
    {
        calculator cal = delegate(int num1,int num2)
        {
            return num1 + num2;
        };
        int he = cal(1, 1);
        Console.Write(he);
    }

下面我們來講解Lambda表示式:

按照上邊的加法,我們用Lambda表示式來實現,程式碼如下:

delegate int calculator(int x, int y); //委託型別
    static void Main()
    {
        calculator cal = (x, y) => x + y;//Lambda表示式,大家發現沒有,程式碼一個比一個簡潔
        int he = cal(1, 1);
        Console.Write(he);
    }

那麼我們詳細講講Lambda表示式:

若要建立 Lambda 表示式,需要在 Lambda 運算子 => 左側指定輸入引數(如果有),然後在另一側輸入表示式或語句塊。 例如,lambda 表示式 x => x * x 指定名為 x 的引數並返回 x 的平方值。 如上面的示例所示,你可以將此表示式分配給委託型別:

"Lambda表示式"是一個特殊的匿名函式,是一種高效的類似於函數語言程式設計的表示式,Lambda簡化了開發中需要編寫的程式碼量。它可以包含表示式和語句,並且可用於建立委託或表示式目錄樹型別,支援帶有可繫結到委託或表示式樹的輸入引數的內聯表示式。所有Lambda表示式都使用Lambda運算子=>,該運算子讀作"goes to"。Lambda運算子的左邊是輸入引數(如果有),右邊是表示式或語句塊。Lambda表示式x => x * x讀作"x goes to x times x"。舉幾個簡單的Lambda表示式,如下:

delegate bool MyBol(int x, int y);
    delegate bool MyBol_2(int x, string y);
    delegate int calculator(int x, int y); //委託型別
    delegate void VS();
    static void Main()
    {
        MyBol Bol = (x, y) => x == y;
        MyBol_2 Bol_2 = (x, s) => s.Length > x;
        calculator C = (X, Y) => X * Y;
        VS S = () => Console.Write("我是無引數Labada表示式");
        //
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        int oddNumbers = numbers.Count(n => n % 2 == 1);
        //
        List<People> people = LoadData();//初始化
        IEnumerable<People> results = people.Where(delegate(People p) { return p.age > 20; });
    }

    private static List<People> LoadData()
    {
        List<People> people = new List<People>();   //建立泛型物件  
        People p1 = new People(21, "guojing");       //建立一個物件  
        People p2 = new People(21, "wujunmin");     //建立一個物件  
        People p3 = new People(20, "muqing");       //建立一個物件  
        People p4 = new People(23, "lupan");        //建立一個物件  
        people.Add(p1);                     //新增一個物件  
        people.Add(p2);                     //新增一個物件  
        people.Add(p3);                     //新增一個物件  
        people.Add(p4);
        return people;
    }

}

public class People
{
    public int age { get; set; }                //設定屬性  
    public string name { get; set; }            //設定屬性  
    public People(int age, string name)      //設定屬性(建構函式構造)  
    {
        this.age = age;                 //初始化屬性值age  
        this.name = name;               //初始化屬性值name  
    }
}

Func委託 T 是引數型別,這是一個泛型型別的委託,用起來很方便的。

先上例子

static void Main(string[] args)
    {
        Func<int, string> gwl = p => p + 10 + "--返回型別為string";            
        Console.WriteLine(gwl(10) + "");   //列印‘20--返回型別為string’,z對應引數b,p對應引數a
        Console.ReadKey();
    }

說明:我們可以看到,這裡的p為int 型別引數, 然而lambda主體返回的是string型別的。

再上一個例子

static void Main(string[] args)
    {
        Func<int, int, bool> gwl = (p, j) =>
            {
                if (p + j == 10)
                {
                    return true;
                }
                return false;
            };
        Console.WriteLine(gwl(5,5) + "");   //列印‘True’,z對應引數b,p對應引數a
        Console.ReadKey();
    }

說明:從這個例子,我們能看到,p為int型別,j為int型別,返回值為bool型別。

至此,如果上邊的內容都能看懂,那麼Lambda也就沒什麼了!

原文請見:https://www.cnblogs.com/mq0036/p/7427892.html

相關文章