C# Lambda運算式

來源:互聯網
上載者:User

"Lambda運算式"是一個匿名函數,是一種高效的類似於函數式編程的運算式,Lambda簡化了開發中需要編寫的代碼量。它可以包含運算式和語句,並且可用於建立委託或運算式分類樹類型,支援帶有可綁定到委託或運算式樹狀架構的輸入參數的內聯運算式。所有Lambda運算式都使用Lambda運算子=>,該運算子讀作"goes to"。Lambda運算子的左邊是輸入參數(如果有),右邊是運算式或語句塊。Lambda運算式x => x * x讀作"x goes to x times x"。可以將此運算式分配給委託類型,如下所示:

  1. delegate int del(int i); 
  2. del myDelegate = x => x * x; 
  3. int j = myDelegate(5); //j = 25

Lambda運算式Lambda運算式是由.NET 2.0演化而來的,也是LINQ的基礎,熟練地掌握Lambda運算式能夠快速地上手LINQ應用開發。

Lambda運算式在一定程度上就是匿名方法的另一種表現形式。為了方便對Lambda運算式的解釋,首先需要建立一個People類,範例程式碼如下。

  1. public class People 
  2.     public int age { get; set; }                //設定屬性 
  3.     public string name { get; set; }            //設定屬性 
  4.     public People(int age,string name)      //設定屬性(建構函式構造) 
  5.     { 
  6.         this.age = age;                 //初始化屬性值age 
  7.         this.name = name;               //初始化屬性值name 
  8.     } 
  9. }

上述代碼定義了一個People類,並包含一個預設的建構函式能夠為People對象進行年齡和名字的初始化。在應用程式設計中,很多情況下需要建立對象的集合,建立對象的集合有利於對對象進行搜尋操作和排序等操作,以便在集合中篩選相應的對象。使用List進行泛型程式設計,可以建立一個對象的集合,範例程式碼如下。

  1. List<People>people = new List<People>();   //建立泛型對象 
  2. People p1 = new People(21,"guojing");       //建立一個對象 
  3. People p2 = new People(21, "wujunmin");     //建立一個對象 
  4. People p3 = new People(20, "muqing");       //建立一個對象 
  5. People p4 = new People(23, "lupan");        //建立一個對象 
  6. people.Add(p1);                     //添加一個對象 
  7. people.Add(p2);                     //添加一個對象 
  8. people.Add(p3);                     //添加一個對象 
  9. people.Add(p4);                     //添加一個對象

上述代碼建立了4個對象,這4個對象分別初始化了年齡和名字,並添加到List列表中。當應用程式需要對列表中的對象進行篩選時,例如需要篩選年齡大於20歲的人,就需要從列表中篩選,範例程式碼如下。

  1. //匿名方法 
  2. IEnumerable<People>results = people.Where (delegate(People p) { return p.age > 20; });

上述代碼通過使用IEnumerable介面建立了一個result集合,並且該集合中填充的是年齡大於20的People對象。細心的讀者能夠發現在這裡使用了一個匿名方法進行篩選,因為該方法沒有名稱,通過使用People類對象的age欄位進行篩選。

雖然上述代碼中執行了篩選操作,但是,使用匿名方法往往不太容易理解和閱讀,而Lambda運算式則更加容易理解和閱讀,範例程式碼如下。

  1. IEnumerable<People>results = people.Where(People => People.age > 20);

上述代碼同樣返回了一個People對象的集合給變數results,但是,其編寫的方法更加容易閱讀,從這裡可以看出Lambda運算式在編寫的格式上和匿名方法非常相似。其實,當編譯器開始編譯並運行時,Lambda運算式最終也表現為匿名方法。

使用匿名方法並不是建立了沒有名稱的方法,實際上編譯器會建立一個方法,這個方法對於開發人員來說是不可見的,該方法會將People類的對象中符合p.age>20的對象返回並填充到集合中。相同地,使用Lambda運算式,當編譯器編譯時間,Lambda運算式同樣會被編譯成一個匿名方法進行相應的操作,但是與匿名方法相比,Lambda運算式更容易閱讀,Lambda運算式的格式如下。

  1. (參數列表)=>運算式或語句塊

上述代碼中,參數列表就是People類,運算式或語句塊就是People.age>20,使用Lambda運算式能夠讓人很容易地理解該語句究竟是如何執行的,雖然匿名方法提供了同樣的功能,卻不容易被理解。相比之下,People => People.age > 20卻能夠很好地理解為"返回一個年紀大於20的人"。其實,Lambda運算式並沒有什麼高深的技術,Lambda運算式可以看作是匿名方法的另一種表現形式。Lambda運算式經過反編譯後,與匿名方法並沒有什麼區別。

比較Lambda運算式和匿名方法,在匿名方法中,"("、")"內是方法的參數的集合,這就對應了Lambda運算式中的"(參數列表)",而匿名方法中"{"、"}"內是方法的語句塊,這對應了Lambda運算式中"=>"符號右邊的運算式或語句塊項。Lambda運算式也包含一些基本的格式,這些基本格式如下。

Lambda運算式可以有多個參數、一個參數,或者沒有參數。其參數類型可以隱式或者顯式。範例程式碼如下:

  1. (x, y) => x * y         //多參數,隱式類型=> 運算式 
  2. x => x * 5              //單參數, 隱式類型=>運算式 
  3. x => { return x * 5; }      //單參數,隱式類型=>語句塊 
  4. (int x) => x * 5            //單參數,顯式類型=>運算式 
  5. (int x) => { return x * 5; }      //單參數,顯式類型=>語句塊 
  6. () => Console.WriteLine()   //無參數

上述格式都是Lambda運算式的合法格式,在編寫Lambda運算式時,可以忽略參數的類型,因為編譯器能夠根據上下文直接推斷參數的類型,範例程式碼如下。

  1. (x, y) => x + y         //多參數,隱式類型=> 運算式

Lambda運算式的主體可以是運算式也可以是語句塊,這樣就節約了代碼的編寫。

【例2-5】傳統方法,匿名方法和Lamdba運算式對比。

(1) 建立控制台應用程式LamdbaPrictice。

(2) 在程式中添加3個函數,這3個函數分別使用傳統的委託調用、使用匿名方法和Lamdba運算式方法完成同一功能,對比有什麼不同。代碼如下:

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. namespace LambdaDemo 
  6.     class Program 
  7.     { 
  8.         static void Main(string[] args) 
  9.         { 
  10.             Console.WriteLine("傳統的委託程式碼範例:"); 
  11.             FindListDelegate(); 
  12.             Console.Write("\n"); 
  13.             Console.WriteLine("使用匿名方法的樣本:"); 
  14.             FindListAnonymousMethod(); 
  15.             Console.Write("\n"); 
  16.             Console.WriteLine("使用Lambda的樣本:"); 
  17.             FindListLambdaExpression(); 
  18.         } 
  19.         //傳統的調用委託的樣本 
  20.         static void FindListDelegate() 
  21.         { 
  22.             //先建立一個泛型的List類 
  23.             List<string>list = new List<string>(); 
  24.          list.AddRange(new string[] { "ASP.NET課程","J2EE課程", "PHP課程", "資料結構課程" }); 
  25.             Predicate<string>findPredicate = new Predicate<string>(IsBookCategory); 
  26.             List<string>bookCategory = list.FindAll(findPredicate); 
  27.             foreach (string str in bookCategory) 
  28.             { 
  29.                 Console.WriteLine("{0}\t", str); 
  30.             } 
  31.         } 
  32.         //謂詞方法,這個方法將被傳遞給FindAll方法進行書書籍分類的判斷 
  33.         static bool IsBookCategory(string str) 
  34.         { 
  35.             return str.EndsWith("課程") ? true : false; 
  36.         } 
  37.         //使用匿名方法來進行搜尋過程 
  38.         static void FindListAnonymousMethod() 
  39.         { 
  40.             //先建立一個泛型的List類 
  41.             List<string>list = new List<string>(); 
  42.          list.AddRange(new string[] { "ASP.NET課程", "J2EE課程", "PHP課程", "資料結構課程" }); 
  43.             //在這裡,使用匿名方法直接為委託建立一個代碼塊,而不用去建立單獨的方法 
  44.             List<string>bookCategory = list.FindAll 
  45.                 (delegate(string str) 
  46.                 { 
  47.                     return str.EndsWith("課程") ? true : false; 
  48.                 } 
  49.                 ); 
  50.             foreach (string str in bookCategory) 
  51.             { 
  52.                 Console.WriteLine("{0}\t", str); 
  53.             } 
  54.         } 
  55.         //使用Lambda來實現搜尋過程 
  56.         static void FindListLambdaExpression() 
  57.         { 
  58.             //先建立一個泛型的List類 
  59.             List<string>list = new List<string>(); 
  60.          list.AddRange(new string[] { "ASP.NET課程", "J2EE課程", "PHP課程", "資料結構課程" }); 
  61.             //在這裡,使用了Lambda來建立一個委託方法 
  62.             List<string>bookCategory = list.FindAll((string str) => str.EndsWith("課程")); 
  63.             foreach (string str in bookCategory) 
  64.             { 
  65.                 Console.WriteLine("{0}\t", str); 
  66.             } 
  67.         } 
  68.     } 
  69. }

程式的運行結果2-7所示。

圖2-7  運行結果
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.