C 學習筆記 lambda表示式

2021-07-07 03:56:35 字數 2354 閱讀 3747

在使用委託的時候,除了將乙個已存在的方法賦給乙個委託之外,還可以使用匿名方法的方式。使用匿名方法的時候,需要乙個delegate關鍵字,並且方法的引數列表要和委託定義的完全一樣。

//這裡有乙個匿名方法

func add = delegate (int a, int b)

;console.writeline($"操作的結果是:");

匿名方法會由編譯器給定乙個名字,無法由使用者使用,使用者也不需要去了解。很明顯,在編寫只呼叫一次的方法時候,匿名方法很有效果。如果乙個方法要在多個地方呼叫,還是寫成命名方法利用名字來呼叫更加合理。

匿名方法有兩個注意事項。

在匿名方法中不能使用跳轉語句跳轉到匿名方法外部,同樣的,匿名方法外部也不能跳轉到方法內部。

在匿名方法內部不能訪問不安全的**,也不能訪問方法外部的ref和out關鍵字。

從c#3.0開始,可以利用lambda表示式來代替匿名方法。所以,任何可以使用委託的地方,都可以使用lambda表示式。例如,上面的 例子就可以利用lambda表示式重寫一下。可以看出,lambda表示式確實比匿名方法更加簡潔。

//這裡有乙個lambda表示式

func add = (a, b) => a + b;

console.writeline($"操作的結果是:");

在這裡,委託是乙個接受兩個int型引數並返回乙個int值的型別,因此對應的lambda表示式也是接受兩個引數並返回乙個值。兩個引數需要寫到括號中,返回值直接由=>右面的表示式給出。因為泛型委託已經給出了具體的引數和返回值的型別,因此lambda表示式不需要寫出返回值,編譯器可以自動推斷出來。如果像這樣在=>右面只有乙個表示式的話,編譯器會計算出它的值並將它當做返回值。

如果方法只有乙個引數的話,就不需要使用括號括起來。就像這樣。

//只有乙個引數的lambda表示式

func sqrt = a => math.sqrt(a);

console.writeline($"表示式的結果是:");

如果沒有引數的話,就使用一對空括號。

//沒有引數的lambda表示式

funcgetpi = () => math.pi;

console.writeline($"表示式的結果是:");

如果方法體需要有多條語句,就必須新增花括號和return語句。

//多行**的lambda表示式

func sub = (a, b) =>

;console.writeline($"表示式的結果是:");

前面的lambda表示式使用的值都是由引數傳遞進去的,這樣的lambda表示式的運算結果顯而易見。但是如果lambda表示式中使用了乙個外部的變數,而不是由引數傳遞進去的值,會發生什麼情況呢。下面的**,執行結果會是什麼樣的呢?

int somevalue = 10;

func f = a => a + somevalue;

somevalue = 20;

console.writeline($"lambda表示式的結果是:");

實際上,在遇到lambda表示式的時候,編譯器會將其編譯成乙個匿名類,外部變數由匿名類的建構函式傳進來。就像這樣:

public

class 匿名類

public

int 匿名方法(int a)

}

呼叫lambda表示式的時候,會建立這個匿名類的乙個新例項,並將外部變數由傳遞進去。所以,上面的**在lambda表示式呼叫的時候,會使用somevalue最新的值,因此上面的**結果為30。

在c#5.0中,foreach語句中的閉包的行為有了很大的變化。以下是《c#高階程式設計》中的乙個例子,非常具有代表性。先猜猜語句執行的結果是什麼。

listvalues = new list;

list> funcs = new list>();

foreach (int val in values)

foreach

(funcfunc in funcs)

在c#5.0之前,這段**的執行結果是三個30。原因如下:編譯器在遇到foreach語句時,會將其轉換為while迴圈。而在c#4中,編譯器會將while迴圈變數建立在while語句外部,因此第乙個迴圈結束之後val的值是30。由於lambda表示式在定義的時候不會獲得val的值,只有在第二個迴圈呼叫的時候才會獲得。因此結果就是三個30。

在c#5中,會在while迴圈中建立乙個不同的區域性變數,因此值會保留下來。所以**的行為會更加自然。這段**的結果是10,20,30。

C 學習筆記 lambda表示式

lambda表示式本質上是一種函式,只要掌握了函式的寫法,完全不學lambda表示式也沒問題。但是,既然有lambda表示式,就有它存在的道理。與通常定義的函式相比,lambda表示式其實是一種匿名函式,就是lambda定義的函式沒有名字。與有名字的函式相比,lambda更簡潔,更適合定義一些功能簡...

C 學習筆記 Lambda表示式

之前在用 linq to sql 時使用過 運算子來進行資料的操作,當時不是很明白這個運算子的 今天碰到一段 也使用這個運算子,甚是好奇。這個運算子是 c 3.0 之後才加進來的,是 lambda 運算子,該運算子讀作 goes to 該運算子左邊是輸入的引數,右邊可以是乙個語句也可以是乙個程式塊。...

學習筆記 Lambda表示式

lambda表示式是c 11中的乙個新特性。如果乙個函式物件只需要呼叫一次,還要專門為其編寫乙個類嗎?如果乙個簡單函式只需要呼叫一次,能否在呼叫時才寫出函式體呢?必須可以,這就是lambda所解決的問題。它可以使程式顯得更加簡潔,更加精神。基本形式 外部變數訪問方式說明符 引數 返回值型別 可以不寫...