【寫給Cpp選手的C#教程】Lambda篇
阿新 • • 發佈:2021-10-05
現在幾乎所有語言都有Lambda表示式了吧,這裡就簡單寫一些。
Lambda表示式的簡單使用
//Lambda表示式的格式如下 //(parameters) => expression-or-statement-block class Program { static int tempFunc(int x) { return x * x; } static void Main() { Func<int, int> id1 = tempFunc; //較為複雜的寫法,是一個語句塊 Func<int, int> id2 =/*往後是Lambda表示式*/ (x) => { return x * x; }; //更加抽象的寫法,一個表示式,第一個x對應引數,x*x的結果對應返回值 Func<int, int> id3 =/*往後是Lambda表示式*/ x => x * x; } }
對於外部變數的捕獲
class Program
{
static void Main()
{
int temp = 4;
Func<int> lambda = () => temp++;
temp = 8;
Console.WriteLine(lambda());
Console.WriteLine(temp);
}
}
如上例所見,我們可以得到以下結論:
①Lambda表示式可以使用函式內部的、表示式外部的變數。
Lambda表示式引用外部變數被稱為捕獲變數(這個好像是動名詞),捕獲變數的表示式稱為閉包。
②函式執行時會傳入外部變數當時的值,而不是外部變數被捕獲時的值。
按照這個例子來看,執行時temp的值是8而不是4,儘管temp是在值為4時被捕獲的。
③函式執行時可以修改外部變數的值。
比如執行lambda之後,temp的值就被改變了。
然後我們來看第二個例子:
class Program { static Func<int> Natual() { int seed = 0; return () => seed++; } static void Main() { Func<int> natual = Natual(); natual(); //seed = 0,函式返回後變成1 natual(); //seed = 1,函式返回後變成2 } }
④捕獲變數的生命週期會延伸到和委託的生命週期一致
體現在,seed在Natual的生命週期中,原先應當隨函式的結束而被銷燬,但現在它的生命週期延長到了和natual委託相同的長度。
據說,被捕獲的變數會被儲存到一個隱藏的類中去,因此它的生命週期變得不同。
Lambda表示式和匿名方法
匿名方法比Lambda表示式缺少了幾個特性:
匿名方法沒有隱式型別的引數;
匿名方法必須是一個語句塊,而不能是表示式;
匿名方法並沒有在賦值給Expression看不懂啦)
public delegate int NumDele(int x);
class Program
{
static void Main()
{
NumDele square = delegate (int x) { return x * x; };
//相當於下面這句
NumDele lambda1 = (x) => {return x* x; };
//相當於下面這句
NumDele lambda2 = x => x * x;
}
}