C# Lambda表達式

来源:http://www.cnblogs.com/lookbs/archive/2017/01/08/Lambda.html
-Advertisement-
Play Games

Linq之Expression進階 Lambda表達式 "Lambda表達式"是一個匿名函數,是一種高效的類似於函數式編程的表達式,Lambda簡化了開發中需要編寫的代碼量。它可以包含表達式和語句,並且可用於創建委托或表達式目錄樹類型,支持帶有可綁定到委托或表達式樹的輸入參數的內聯表達式。所有Lam ...


Linq之Expression進階

Lambda表達式

"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. {  
  3.     public int age { get; set; }                //設置屬性  
  4.     public string name { get; set; }            //設置屬性  
  5.     public People(int age,string name)      //設置屬性(構造函數構造)  
  6.     {  
  7.         this.age = age;                 //初始化屬性值age  
  8.         this.name = name;               //初始化屬性值name  
  9.     }  

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

  1. List<Peoplepeople = 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<Peopleresults = people.Where
    (delegate(People p) { return p.age > 20; }); 

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

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

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

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

 
圖2-7  運行結果
 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • First: 找到符合條件的第一記錄,就返回了,不管後面還有多少數據。 Single: 先將記錄都梳理一次,再找到符合要求的唯一記錄。 Single():操作一個集合,同時強要求只有一個對象匹配,並返回這一個。 First():操作一個集合,可以有多個對象匹配,但是只返回第一個。 Take(1):操 ...
  • 前言 這一篇實現snsapi_userinfo,寫這篇時其實我是有疑惑的,因為我並沒有調試成功,但是我反覆檢查程式和思路是沒有問題的,因為我使用的測試公眾號,群里一個伙計說他之前調試時用的也是測試公眾號也遇到了和我一樣的問題,然後換上正式公眾號就好了。而且我再三檢查了微信開發文檔里,snsapi_u ...
  • 前言 微信網頁授權共分為兩種方式:snsapi_base、snsapi_userinfo。 snsapi_base需要關註公眾號,獲取用戶信息時不彈出用戶授權界面。 snsapi_userinfo是在用戶未關註公眾號的情況下瀏覽頁面,會先彈出一個用戶授權界面,用戶授權後才能拿到用戶信息。這一篇我們先 ...
  • 前言 一切準備工作就緒時就先實現一個關註公眾號後向客戶端推送一條消息。關註後推送消息需要一個get請求、一個post請求,get請求主要是為了向微信伺服器驗證,post請求主要就是處理微信消息了。 調介面時傳遞的appid和appsecret請傳遞自己公眾號對應的參數。 微信事件交互 微信事件交互主 ...
  • 淺談類和對象的概念 一、什麼是類?什麼是對象? 學習一門面向對象編程語言,我們必須得知道什麼是類?什麼是對象? 類(Class)實際上是對某種類型的對象定義變數和方法的原型。它表示對現實生活中一類具有共同特征的事物的抽象,是面向對象編程的基礎。 簡單地說,類是一種抽象的數據類型,是對一類對象的統一描 ...
  • 前言 最初打算熟悉下微信開發打算用node.js開發,結果底氣不足先用C#開發,先踩了踩坑。 準備工作 微信公眾平臺開發者文檔。 這個先多看幾遍。 測試公眾號,申請開通後會看到微信號,appID,appsecret。開通後可以看到掃描下方的二維碼關註該測試公眾號 功能變數名稱。功能變數名稱和伺服器的話大家可以買阿裡 ...
  • 靜態、非靜態 先來看一段代碼來區分靜態與非靜態: 可以看出靜態與非靜態的區別在於 關鍵字 : static 靜態和非靜態的區別: 1)、在非靜態類中,既可以有實例成員,也可以有靜態成員。 2)、在調用實例成員的時候,需要使用對象名.實例成員; 在調用靜態成員的時候,需要使用類名.靜態成員名; 3)、 ...
  • 一.方法: ContainerFromIndex:返回 ItemCollection 中指定索引處的項的容器。 ContainerFromItem:返回與制定的項對應的容器(ComboxItem等條目控制項)。 Equals(Object):確定製定的Object是否等於當前的Object。 Fina ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...