理解C#中的Lambda表達(dá)式
先來(lái)看兩段代碼:
Thread t = new Thread(() =>
{
AddIt AddDelegate = new AddIt(AddItem);
this.Invoke(AddDelegate);
});
Thread t3 = new Thread(new ThreadStart(() =>
{
AddIt AddDelegate = new AddIt(AddItem);
this.Invoke(AddDelegate);
}));
這兩種寫(xiě)法都是可以的,出來(lái)的IL也一樣,但是意義是不同的,后者相當(dāng)于匿名方法,前者
更像是"匿名"的委托,其實(shí)這樣寫(xiě):
Thread t2 = new Thread(() =>
{
this.Invoke(new AddIt(() => { this.listBox1.Items.Add("bbb"); }));
});
這個(gè)跟上面兩種寫(xiě)法也是一樣的效果,初次接觸的時(shí)候,可能大家跟我一樣會(huì)有些迷茫,Lamdba表達(dá)式到底該怎么用呢?
首先還是要弄清Lamdba表達(dá)式的幾個(gè)特性:
1. Lamdba 表達(dá)式是一個(gè)委托類(lèi)型:
MethodInvoker invoker = () => { Console.WriteLine(); };
//is actually equal to the following form.
MethodInvoker invoker = delegate() { Console.WriteLine(); };
//這里是Lamdba 表達(dá)式的匿名委托的用法
2. Lamdba 表達(dá)式可以用作匿名方法
MethodInvoker invoker = new MethodInvoker(() => { Console.WriteLine(); });
//相當(dāng)于:
MethodInvoker invoker = new MethodInvoker(MyFunc);
partial void MyFunc()
{
Console.WriteLine();
}
我們知道, 當(dāng)構(gòu)造一個(gè)新的委托的時(shí)候, 他的構(gòu)造器需要一個(gè)函數(shù)指針作參數(shù),這個(gè)函數(shù)指針是委托類(lèi)型的
實(shí)際上,當(dāng)我們這樣去new 一個(gè)委托的時(shí)候:
MethodInvoker invoker = new MethodInvoker(MyFunc);
"MyFunc" 就是一個(gè)委托,而不只是一個(gè)函數(shù)名的存在. 編譯器將為這個(gè)構(gòu)造函數(shù)生成一個(gè)匿名委托:
MethodInvoker invoker = new MethodInvoker(delegate() { MyFunc(); });
可以這樣理解編譯器的行為: 匿名方法其實(shí)也就是委托。
那么為什么我們可以這么寫(xiě)呢:
MethodInvoker invoker = () => { Console.WriteLine(); };
我們來(lái)看一看:
首先,這個(gè)委托的構(gòu)造器需要一個(gè)委托參數(shù),所以通常我們得這樣寫(xiě):
MethodInvoker invoker = new MethodInvoker(delegate() { MyFunc(); });
但是匿名的delegate 可以轉(zhuǎn)化成函數(shù)指針 (void() target):
所以這樣寫(xiě)是可以的:
MethodInvoker invoker = new MethodInvoker(MyFunc);
//而匿名的委托又可以描述為L(zhǎng)ambda表達(dá)式
MethodInvoker invoker = new MethodInvoker(() => { Console.WriteLine(); });
//另外一方面,由于編譯器對(duì)"寬松委托"的支持, MethodInvoker類(lèi)委托可以轉(zhuǎn)化成匿名類(lèi)委托:
MethodInvoker invoker = delegate() { Console.WriteLine(); };
//而匿名的委托又可以用Lambda表達(dá)式來(lái)描述
MethodInvoker invoker = () => { Console.WriteLine(); };
從上面,我們可以看到一個(gè)復(fù)雜的委托是如何轉(zhuǎn)化成簡(jiǎn)潔的Lambda表達(dá)式的。這對(duì)程序員來(lái)說(shuō)無(wú)疑又是提高生產(chǎn)力的一個(gè)體現(xiàn)!
相關(guān)文章
C# 文件下載之?dāng)帱c(diǎn)續(xù)傳實(shí)現(xiàn)代碼
本篇文章主要介紹了C# 文件下載之?dāng)帱c(diǎn)續(xù)傳實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01C#將隱私信息(銀行賬戶(hù),身份證號(hào)碼)中間部分特殊字符替換成*
大家在銀行交易某些業(yè)務(wù)時(shí),都可以看到無(wú)論是身份證、銀行賬號(hào)中間部分都是用*號(hào)替換的,下面這篇文章主要介紹C#將隱私信息(銀行賬戶(hù),身份證號(hào)碼)中間部分特殊字符替換成*的相關(guān)資料,需要的朋友可以參考下2015-08-08一個(gè)C#開(kāi)發(fā)者重溫C++的心路歷程
作為一個(gè)C#開(kāi)發(fā)為什么要重新學(xué)習(xí)C++呢?因?yàn)樵贑#在很多業(yè)務(wù)場(chǎng)景需要調(diào)用一些C++編寫(xiě)的COM組件,如果不了解C++,那么,很容易。。。注定是要被C++同事忽悠的2019-05-05通過(guò)VS中的數(shù)據(jù)源選擇對(duì)話(huà)框簡(jiǎn)單實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接配置[圖]
通過(guò)VS中的數(shù)據(jù)源選擇對(duì)話(huà)框簡(jiǎn)單實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接配置[圖]...2007-03-03C#數(shù)值轉(zhuǎn)換-顯式數(shù)值轉(zhuǎn)換表(參考)
就是在將一種類(lèi)型轉(zhuǎn)換成另外一種類(lèi)型時(shí),需要額外的代碼來(lái)完成這種轉(zhuǎn)換。2013-04-04C#中把Datatable轉(zhuǎn)換為Json的5個(gè)代碼實(shí)例
這篇文章主要介紹了C#中把Datatable轉(zhuǎn)換為Json的5個(gè)代碼實(shí)例,需要的朋友可以參考下2014-04-04C#程序中使用LINQ to XML來(lái)查詢(xún)XML格式數(shù)據(jù)的實(shí)例
這篇文章主要介紹了C#程序中使用LINQ to XML來(lái)查詢(xún)XML格式數(shù)據(jù)的實(shí)例,LINQ to XML是.NET框架中集成的接口,可以將XML數(shù)據(jù)放到內(nèi)存中進(jìn)行處理,需要的朋友可以參考下2016-03-03WPF自定義實(shí)現(xiàn)雷達(dá)圖控件的示例詳解
雷達(dá)圖用于表示不同內(nèi)容的占比關(guān)系,在項(xiàng)目中有廣泛的應(yīng)用,但是目前未曾有封裝良好的雷達(dá)圖控件,所以本文分享了如何封裝一個(gè)通用的雷達(dá)圖控件,希望對(duì)大家有所幫助2023-08-08C#使用Sleep(Int32)方法實(shí)現(xiàn)動(dòng)態(tài)顯示時(shí)間
這篇文章主要為大家詳細(xì)介紹了C#如何使用Sleep(Int32)方法實(shí)現(xiàn)動(dòng)態(tài)顯示時(shí)間,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2024-01-01