CSharp 基礎知識系列- 6 Lambda表達式和Linq簡單介紹

2021-01-10 程式設計師小高學習筆記

前言

C#的lambda和Linq可以說是一大亮點,C#的Lambda無處不在,Linq在數據查詢上也有著舉足輕重的地位。

那麼什麼是Linq呢,Linq是Language Intergrated Query(語言集成查詢)的縮寫,可以對本地對象集合或者遠程數據源進行結構化的查詢操作。

那什麼又是Lambda呢?嗯,簡單來講就是匿名函數,我們不聲明方法名,只寫一個方法體,這個方法體就是lambda表達式

1. lambda表達式

1.1 如何寫一個lambda表達式

首先,在寫lambda表達式之前,需要先了解兩個特殊的類型:Func和Action。

這是兩個委託,這裡先不急著了解什麼是委託,可以把它們當做一種名稱規範就行,它們都可以表示一個方法。不同的是其中Func表示一個有返回值的方法,Action表示一個沒有返回值的方法。C#對這兩個的定義如下:

public delegate TResult Func<out TResult>();//注意這裡的out 表示這個泛型是返回值的類型泛型

public delegate void Action();

其中Func和Action各有16個變種:

// 注意 in 關鍵字,表示泛型是參數的類型約束public delegate TResult Func<in T,out TResult>(T arg);public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1, T2 arg2);……public delegate TResult Func<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16,out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);////public delegate void Action<in T>(T obj);public delegate void Action<in T1,in T2>(T1 arg1, T2 arg2);……public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);

依次表示一個參數、兩個參數、……十六個參數 的方法。當然,你還可以寫更多的參數,但是如果一個方法的參數超過10個,為什麼不用類封裝起來呢?即使不封裝,一個方法十幾個參數,你確定不會被你的領導嫌棄嗎。

言歸正傳,介紹完了Func和Action的定義,那麼如果使用呢?

public void Demo1()

{

// 一個沒有返回值,也沒有參數的方法

}

Action act1 = Demo;// 直接給一個方法名

public void Demo2(string name)

{

//有一個參數,但沒有返回值的方法

}

Action<string> act2 = Demo2;

public String Demo3()

{

// 有返回值,但沒有參數的方法

}

Func<string> func1 = Demo3;

public int Demo4(double data)

{

// 返回值是int,有一個參數是double的方法

}

Func<double,int> func2 = Demo4;

以上是通過方法名獲取Func和Action的方法,下面介紹一下通過Lambda表達式的方式創建Func和Action:

Action act1 = ()=> // lambda 的標誌性 聲明方式 =>

{

// 這是一個沒有返回值,也沒有參數的 lambda表達式

};

Action<int> act2 = (age) =>

{

// 這是一個 參數為int ,沒有返回值的 lambda表達式

};

//=========================================

Func<string> func1 = () => ""; // 這是一個返回了空字符串的lambda表達式,注意這種寫法

Func<string> func2 = () =>

{

return ""; //與上一個等價

}

Func<int,string> func3 = (age) =>

{

return "我的年紀是:"+age;// 一個參數是int,返回類型是string的lambda表達式

}

在lambda表達式中,當使用的是有返回值的方法體時,如果方法體是個簡單的計算式或者說可以在一行內寫完(或被編譯器認為是一行)的話,可以省略{、}和return,直接用=>標記。

比如說以下內容:

Func<int,int,int> cal_area = (width, height) => width * height;// 計算面積

使用Lambda 表達式

現在我們手裡有一大堆的Action和Func,我們該怎麼用呢?

有以下兩種常見的用法:

把它當做方法來用:

// 上接上文代碼

act1();// 執行 act1 代表的方法或lambda表達式

act2(10); //執行act2 的lambda表達式

string str1 = func1();

string str2 = func3(10);

int area = cal_area(29,39);

調用Invoke方法:

act1.Invoke();

act2.Invoke(10);

area = cal_area.Invoke(33,63);

看過反射篇的應該對Invoke有一定印象,這個與MethodInfo裡的Invoke類似,但是比其更加簡單。

Linq 是什麼

正如前言所述,Linq是一種對集合、數據源的集成式查詢方式,它是對IEnumerable<T>的擴展方法集,所以想要使用Linq的話,需要引用兩個命名空間System.Linq和System.Linq.Expressions。

Linq有兩種使用方式,一種是通過方法鏈的方式調用,一種是類似SQL語句的方式進行數據查詢。方法鏈是基礎,類SQL方式是語法糖。下面簡單介紹一下兩種方式的使用,不過首先先假設我們有一個數據很多的集合:

IEnumerable<int> scores = new List<int>();//假設存放了某班50個人的語文成績

使用方法鏈查詢

獲取分數大於60的所有分數:

IEnumerable<int> result1 = scores.Where(t => t > 60);

獲取分數大於等於60的數量:

int count = scores.Count(t => t >= 60);

統計分數總和

int sum = scores.Sum();

獲取所有分數個位上的數字:

IEnumerable<int> result2 = scores.Select(t => t % 10);

使用類SQL形式查詢

查詢所有大於等於60的分數:

IEnumerable<int> result3 = from score in scores

where score >= 60

select score;

簡單介紹一下,類SQL形式有一個統一的格式寫法,關鍵字from、in、select缺一不可:

from 臨時變量名 in 數據源select 結果類型

where 是條件過濾,如果查詢全部,可以忽略。

這種方式之所以被我稱為是類SQL形式,是因為它的寫法和SQL及其相似,熟悉SQL的可以很快上手。

為什麼說方法鏈是基礎呢?

因為SQL形式的查詢裡每一個關鍵字背後都有一個方法作為支撐,除了from 和in。

select 對應的Select 方法,where對應的Where方法。

需要特別注意的一點:

Linq查詢是一種延遲查詢,也就是說當返回類型是一個IEnumerable 的時候不會立即返回結果,必須調用ToList才能獲取到實際查詢結果。另外需要注意的是,ToList返回的是一個不可變List集合,這一點在集合篇中做過介紹了。

未完待續

C#裡的Linq內容如此豐富,以至於一時間無法詳細說明,後續還會有兩到三篇關於Linq的內容,今天就先到這裡了。

相關焦點

  • Java8 lambda表達式語法
    文中如有錯誤和理解偏差的地方,希望大家幫忙指出,我會持續修改和優化。本文是該系列的第一篇,主要介紹Java8對屌絲碼農最有吸引力的一個特性—lambda表達式。java8的安裝工欲善其器必先利其器,首先安裝JDK8。過程省略,大家應該都可以自己搞定。
  • Python匿名函數:Lambda表達式
    首先,看一個返回所有參數和的函數:# 返回所有參數和def pSum(a,b,c):return a + b + cpSum(10,40,50)函數中必須要用return才能實現「和」的返回。接著我們嘗試用lambda表達式來實現上述函數功能:# labmda表達式psum = lambda a,b,c:a + b + cprint(psum) # 驗證是否生成一個新對象
  • Python中的Lambda表達式
    Lambda表達式當我們需要做一些簡單的事情並且更希望快速完成工作而不是正式命名函數時,Lambda表達式是理想的選擇。Lambda表達式也稱為匿名函數。Python中的Lambda表達式是聲明小型匿名函數的一種簡短方式(沒有必要為Lambda函數提供名稱)。
  • 「數據清洗」lambda表達式配合使用的四種函數
    >lambda 表達式是一個匿名函數,lambda表達式基於數學中的λ演算得名,直接對應於其中的lambda抽象,是一個匿名函數,即沒有函數名的函數。lambda函數有輸入和輸出:輸入是傳入到參數列表argument_list的值,輸出是根據表達式expression計算得到的值。lambda函數一般功能簡單:單行expression決定了lambda函數不可能完成太過複雜的邏輯,只能完成較為簡單的功能。
  • python入門基礎之lambda匿名函數詳解
    python入門基礎之lambda匿名函數詳解剛開始學習python的時候很多人可能對於lambda函數不了解,感覺和def很混亂,下面我來介紹一下lambda函數我從一下幾個方面來介紹lambda:一個完整的 lambda"語句"代表了一個表達式,這個表達式的定義體必須和聲明放在同一行。
  • Java8 lambda表達式
    ,event是參數,同匿名內部類的參數一樣,->將參數和lambda表達式的內容體分開。如何在正確的場合使用lambda表達式?下面有幾個使用lambda表達式的例子①展示了在沒有參數的情況下如何使用lambda,可以使用一對空的小括號來表示沒有參數,這是一個實現了Runnable的lambda的表達式,該接口只有一個方法run(),該方法不接受任何參數,且返回void.
  • Lambda表達式在Python事件中的運用
    本篇筆記內容:Lambda表達式詳解Lambda表達式在事件中的應用【1】Lambda表達式詳解lambda 表達式定義的是一個匿名函數,只適合簡單輸入參數,簡單計算返回結果,不適合功能複雜情況。lambda 定義的匿名函數也有輸入、也有輸出,只是沒有名字。語法格式如下:lambda 參數值列表:表達式其中,參數值列表即為輸入,表達式計算的結構即為輸出。看一個案例:求三個數的和。
  • Python每天一分鐘:lambda表達式 (匿名函數)及用法詳解
    lambda表達式介紹python中有一種靈活,便捷的且具有函數功能的表達式:lambda表達式!,它可以在程序中被傳遞和調用。lambda 表達式可以用來替換局部函數(感興趣的讀者可以自行查閱「局部函數」),下面為大家演示lambda表達式的具體用法。
  • 三種基本用法、五種應用場景,理清C++11新特性:Lambda表達式
    lambda表達式是指能夠捕獲作用域中的變量的無名函數對象,狹義的理解,就是匿名函數。無論是在項目中,還是在開源網站,總是能夠看到lambda的身影。為了能夠輕鬆閱讀代碼,進而熟練地使用,本文首先將講解lambda表達式的基本語法、三種基本用法,然後介紹五種實際的應用場景,最有總結說明lambda表達式的作用。
  • Python學習第40課-Lambda表達式創建匿名函數
    Python中可以使用Lambda表達式來創建匿名函數。lambda表達式用來創建匿名函數,那麼我們也可以把lambda表達式叫做lambda函數。●Lambda函數的特點lambda函數只需要寫一行代碼,函數體比用def定義的函數體簡單。lambda函數有自己的命名空間,且不能訪問自己命名空間之外或全局命名空間裡的參數。
  • Java中Lambda表達式的5種不同語法
    表達式的標準語法包括以下內容:1.主體,由單個表達式或語句塊組成。在上面的代碼中,可以將m和n的類型推斷為String,因此可以省略該類型。這使代碼更整潔,更像真正的lambda表達式。3. Lambda表達式中的多行代碼如果代碼不能一行編寫,則可以將其括在{}中。現在,該代碼應明確包含return語句。
  • 大家都在說的「Lambda 表達式」到底是什麼?
    自從java8中引入了Lambda表達式之後,使用的人也越來越多了,這篇文章我們就來看看什麼是Lambda表達式。廢話少說,先看定義!01定義Lambda表達式也被稱為箭頭函數,匿名函數,閉包Lambda表達式體現的是輕量級函數式編程思想『->』符號式Lambda表達式核心操作符號,符號左側是操作參數,符號右側是操作表達式1、在定義中有一個比較重要的詞就是「函數式編程」現在「
  • 正則表達式的基礎知識和Python中的基本應用
    正則表達式通常被用來檢索、替換那些符合某個模式(規則)的文本,簡單來說它就是記錄文本規則的代碼,再通過這種規則判斷和篩選字符串。多種程序設計語言支持正則表達式,Python也不例外。正則表達式其實就是立規矩的設置代碼今天來學習一些使用正則表達式需要掌握的一些知識。
  • Python面試題推薦:什麼是lambda函數?
    別忘了自己整理相關Python知識,祝大家面試順利!Python允許你定義一種單行的小函數。定義lambda函數的形式如下:labmda 參數:表達式lambda函數默認返回表達式的值。你也可以將其賦值給一個變量。
  • lambda匿名函數都自嘆不如
    其中,一行代碼編寫與lambda表達式是最具代表性的方法,下面分別來介紹一行代碼編寫和lambda表達式的代碼之美。一行代碼我們都知道,創建列表的方式有多種,比如直接定義、使用list()函數轉換、使用for循環迭代輸出等等。
  • C語言中的運算符和表達式
    一、賦值運算符和賦值表達式1、賦值運算符C語言的賦值運算符為等號,表示形式「=」。此外,還有複合賦值運算符,後續陸續介紹。6、複合賦值運算符複合賦值運算符有:+=、-=、*=、/=、%=,分別等同於以下:x+=y+1等同x=x+(y+1)依次類推,注意:右側表達式為一個整體。
  • Python語言教程算術運算與算術表達式的介紹
    Python語言教程算術運算與算術表達式的介紹 Python語言教程在算術運算符與算術的表達方式是我們值得學習的知識。下面我們就來詳細的看看Python語言教程中的相關信息。
  • C語言基礎知識學習(一)
    C程序基礎1. 標識符在程序中使用的變量名、函數名、數組名、指針名、標號等稱為標識符.,所有浮點型都要轉換為double型再進行運算,char和short必須轉換為int型,在賦值運算時=右邊的轉換為左邊的。
  • 單片機c語言教程:C51運算符和表達式
    運算符按其表達式中與運算符的關係可分為單目運算符,雙目運算符和三目運算符。單目就是指需要有一個運算對象,雙目就要求有兩個運 算對象,三目則要三個運算對象。表達式則是由運算及運算對象所組成的具有特定含義的式 子。C 是一種表達式語言,表達式後面加「;」號就構成了一個表達式語句。
  • Python小白學習記錄-匿名函數lambda
    匿名函數就是不需要通過def定義及顯示地指定函數名的函數匿名函數的特性(1)匿名函數只能有一個表達式,不用寫return,返回值就是該表達式的結果。(4)有些函數在代碼中只用一次,而且函數體比較簡單,不需要賦值給變量,直接調用可以減少代碼量,看起來比較」優雅「。