C 匿名方法和Lambda表示式

2022-02-14 18:46:54 字數 4005 閱讀 9581

1. 需要乙個臨時方法,這個方法只會使用一次,或者使用的很少。

2. 這個方法的方法體很短,以至於比方法宣告都短,寫起來實在沒勁(我將其稱之為「一句話方法」)。

沒辦法,這樣的方法寫起來真是吃力不討好,比如一些按鈕事件處理中,有些按鈕點選就是彈出乙個對話方塊,或者呼叫一下別的什麼方法。比如下面的**:

this.btnrefresh.click += 

newsystem.eventhandler(this.btnrefresh_click);

private

void

btnrefresh_click(

object

sender, eventargs e)

這個」refresh」按鈕就是做一下呼叫一下binddata()資料繫結的方法,為此我們不得不寫乙個新方法。好了,c# 2.0為我們提供了匿名方法:

this.btnrefresh.click += delegate(

object

sender, eventargs e) ;

沒勁的**沒了。想知道這種寫法的幕後**麼?

其實編譯器還是在我們的後面幹了一件齷齪的事情:它為我們產生了乙個新的方法,它只是表面上為我們節省了**。

privatevoidb__0(

object

sender, eventargs e)

看看這個編譯器產生的方法的名稱:

b_0,test是這個匿名方法所放置的地方(因為這個按鈕的時間我是放在乙個test方法裡的) 還有一點需要注意的是,如果這個匿名方法是在例項方法裡使用,那麼編譯器為我們生成的幕後方法也是例項方法,否則就是靜態方法了。

是不是覺得匿名方法這東西很不錯,減少了很多**阿,但是匿名方法的使用還並不人性化,什麼是人性化呢?比如你可以用自然的語言將程式**讀出來,這樣才算人性化了.在.net 2.0中system.collections.generic命名空間下list裡有一些新增的方法。比如find,如果使用匿名方法我們如何呼叫呢:

books.find(delegate(book book));

**是很簡單,但是卻無法朗讀出來,來看看lambda表示式的寫法:

好了,那我們就走進lambda表示式吧:

將使用了lambda表示式的程式集反編譯後,我們發現,它實際上和匿名方法沒有什麼不同。lambda的輸入引數就對應著delegate括號裡面的引數,由於lambda表示式可以推斷引數的型別,所以這裡的引數無需宣告。

lambda操作符讀作」goes to」,它後面緊跟著表示式或者是語句塊(這點和匿名方法也不同,匿名方法只能使用語句塊而不能使用表示式),下面我就用例項來說明一下有那些型別的lambda表示式:

//x的型別省略了,編譯器可以根據上下文推斷出來,後面跟著的是表示式

//x的型別省略了,編譯器可以根據上下文推斷出來,後面跟著的是表示式

x =>x+

1deleage(

intx)

//後面跟著的是語句塊

x=>

delegate

(int

x)//

輸入引數也可以帶型別,帶型別後別忘記小括號哦

(int

x) =>x+

1delegate

(int

x)//

也可以多個輸入引數,逗號分隔,別忘記小括號

(x,y) 

=>x+

ydelegate

(int

x,int

y)//

無參的也行

() =>

1delegate

()對於lambda表示式來說她的用法就是如此,但是在lambda背後卻有很多的故事和玄機。用lambda表示式可以構建表示式樹,而表示式樹對於linq來說就像樹根對於樹一樣重要。在這裡就不討論表示式樹的問題了,這個東西也不是三言兩語能夠說清楚的,等待時機成熟的時候我們再來進一步討論。

*************:

1. 需要乙個臨時方法,這個方法只會使用一次,或者使用的很少。

2. 這個方法的方法體很短,以至於比方法宣告都短,寫起來實在沒勁(我將其稱之為「一句話方法」)。

沒辦法,這樣的方法寫起來真是吃力不討好,比如一些按鈕事件處理中,有些按鈕點選就是彈出乙個對話方塊,或者呼叫一下別的什麼方法。比如下面的**:

this.btnrefresh.click += 

newsystem.eventhandler(this.btnrefresh_click);

private

void

btnrefresh_click(

object

sender, eventargs e)

這個」refresh」按鈕就是做一下呼叫一下binddata()資料繫結的方法,為此我們不得不寫乙個新方法。好了,c# 2.0為我們提供了匿名方法:

this.btnrefresh.click += delegate(

object

sender, eventargs e) ;

沒勁的**沒了。想知道這種寫法的幕後**麼?

其實編譯器還是在我們的後面幹了一件齷齪的事情:它為我們產生了乙個新的方法,它只是表面上為我們節省了**。

privatevoidb__0(

object

sender, eventargs e)

看看這個編譯器產生的方法的名稱:

b_0,test是這個匿名方法所放置的地方(因為這個按鈕的時間我是放在乙個test方法裡的) 還有一點需要注意的是,如果這個匿名方法是在例項方法裡使用,那麼編譯器為我們生成的幕後方法也是例項方法,否則就是靜態方法了。

是不是覺得匿名方法這東西很不錯,減少了很多**阿,但是匿名方法的使用還並不人性化,什麼是人性化呢?比如你可以用自然的語言將程式**讀出來,這樣才算人性化了.在.net 2.0中system.collections.generic命名空間下list裡有一些新增的方法。比如find,如果使用匿名方法我們如何呼叫呢:

books.find(delegate(book book));

**是很簡單,但是卻無法朗讀出來,來看看lambda表示式的寫法:

好了,那我們就走進lambda表示式吧:

將使用了lambda表示式的程式集反編譯後,我們發現,它實際上和匿名方法沒有什麼不同。lambda的輸入引數就對應著delegate括號裡面的引數,由於lambda表示式可以推斷引數的型別,所以這裡的引數無需宣告。

lambda操作符讀作」goes to」,它後面緊跟著表示式或者是語句塊(這點和匿名方法也不同,匿名方法只能使用語句塊而不能使用表示式),下面我就用例項來說明一下有那些型別的lambda表示式:

//x的型別省略了,編譯器可以根據上下文推斷出來,後面跟著的是表示式

//x的型別省略了,編譯器可以根據上下文推斷出來,後面跟著的是表示式

x =>x+

1deleage(

intx)

//後面跟著的是語句塊

x=>

delegate

(int

x)//

輸入引數也可以帶型別,帶型別後別忘記小括號哦

(int

x) =>x+

1delegate

(int

x)//

也可以多個輸入引數,逗號分隔,別忘記小括號

(x,y) 

=>x+

ydelegate

(int

x,int

y)//

無參的也行

() =>

1delegate

()對於lambda表示式來說她的用法就是如此,但是在lambda背後卻有很多的故事和玄機。用lambda表示式可以構建表示式樹,而表示式樹對於linq來說就像樹根對於樹一樣重要。在這裡就不討論表示式樹的問題了,這個東西也不是三言兩語能夠說清楚的,等待時機成熟的時候我們再來進一步討論。

*************:

C 匿名方法和Lambda表示式

有一次看見別人的 裡 以及花裡胡哨的省略寫法感覺好炫酷,就去整理了一下匿名方法和lambda表示式的寫法。1.無返回值型別actiontellname delegate string name 2.委託為方法引數時,省略構造委託例項listlistarray new list listarray.f...

C 匿名方法和Lambda表示式

1.需要乙個臨時方法,這個方法只會使用一次,或者使用的很少。2.這個方法的方法體很短,以至於比方法宣告都短,寫起來實在沒勁 我將其稱之為 一句話方法 沒辦法,這樣的方法寫起來真是吃力不討好,比如一些按鈕事件處理中,有些按鈕點選就是彈出乙個對話方塊,或者呼叫一下別的什麼方法。比如下面的 this.bt...

匿名方法和Lambda表示式

出於mvvm學習的需要,複習下匿名方法和lambda表示式,因為之前用的也比較少,所以用的也不是很熟練,baidu下相關的知識,寫了這個demo,目標是用簡單的方法展示這個怎麼用。這裡偏重的和linq中的lambda表示式 var fileslookup files.tolookup f f.sub...