匿名函式 委託和Lambda表示式

2022-05-14 02:44:03 字數 3098 閱讀 8164

其中匿名的函式簽名可以包括兩種,一種是隱式的匿名函式簽名另一種是顯式的匿名函式簽名: 

隱式的函式簽名:(p)、(p1,p1) 

顯式的函式簽名:(int p)、(int p1,int p2)、(ref int p1,out int p2) 

匿名的函式體可以是表示式或者**塊。

從上面我們可以看出,lambda表示式的引數形式可以顯式或者隱式型別化。在顯式型別化引數列表中,每個引數的型別是顯式宣告的,在隱式型別化引數列表中,引數的型別是從匿名函式出現的上下文中推斷出來的。 

當lambda表示式只有乙個具有隱式型別化引數的時候,引數列表可以省略圓括號,也就是說: 

(引數) => 表示式 

可以簡寫為 

引數 => 表示式

一些匿名函式的示例

x => x + 1 //隱式的型別化,函式體為表示式 

x => //隱式的型別化,函式體為**塊 

(int x) => x + 1 //顯式的型別化,函式體為表示式 

(int x) => //顯式的型別化,函式體為**塊 

(x , y) => x * y //多引數 

() => console.writeline() //無引數 

async (t1 , t2) => await t1 + await t2 //非同步 

delegate (int x) //匿名函式方法表示式 

delegate //引數列表省略 

lambda表示式和匿名方法表示式的區別:

● 當沒有引數的時候,匿名方法表示式允許完全省略引數列表,從而可以轉換為具有任意值引數列表的委託型別,lambda表示式則不能省略引數列表的圓括號()。 

● lambda表示式允許省略和推斷型別引數,而匿名方法表示式要求顯式宣告引數型別。 

● lambda表示式主體可以為表示式或者**塊,而匿名方法表示式的主體必須為**塊。 

● 只有lambda表示式可以相容到表示式樹型別。

乙個委託是乙個指向乙個方法的引用,或者說,乙個委託的例項就是乙個指向某個方法的物件,這是乙個簡單卻十分強大的概念。

c#中的委託是用來處理在其他語言中(如c++、pascal等)需要用函式指標來處理的情況。不過與c++不同的是:委託是完全物件導向的;c++指標僅僅指向成員函式,而委託同時封裝了物件的例項和方法;委託是完全型別安全的,只有當函式的簽名與委託的簽名匹配的時候,委託才可以指向該方法,當委託沒有合法的指向方法的時候不能被呼叫。

一些關於委託的知識點:

1.委託是型別安全的

委託型別的返回型別必須為void或者輸出安全,委託型別的所有形參型別都必須是輸入安全的。 

2.委託型別是名稱等效,不是結構等效

也就是說,對於兩個委託型別,即使它們具有相同的引數列表和返回型別,它們仍將被視為兩個不同的委託型別。 

例如: 

delegate int a(int x); 

delegate int b(int x); 

a和b是兩個不同的委託。 

但是,兩個結構一樣的委託,它們的例項可以指向同乙個方法。 

3.委託的呼叫列表(多播委託)

委託例項所封裝的方法集合稱為呼叫列表。 

當我們從某個方法建立乙個委託例項的時候,該例項將封裝此方法,該例項中的呼叫列表包含乙個「入口點」。當我們組合多個非空的委託例項的時候,它們的呼叫列表將連線在一起形成乙個新的呼叫列表,新的呼叫列表中包含了多個「入口點」。 

委託的組合是使用二元運算子 + 和 += 來進行的,同樣可以使用 - 和 -= 來進行組合的移除。 

下面的示例演示多個委託的例項化及其相應的呼叫列表:

1

delegate

void d(intx)2

class35

public

static

void m2(inti)6

}7class

test

817 }

例項化cd1和cd2的時候,它們分別封裝乙個方。例項化cd3的時候,它呼叫的列表有兩個方法m1和m2,而且順序與此相同。cd4的呼叫列表中依次包含m1、m2、m1。最後,cd5的呼叫列表中依次包含m2、m1、m1、m2。 

4.委託的呼叫

當呼叫乙個委託例項的時候,將按照呼叫列表的順序依次呼叫列表中的各個方法,當在呼叫期間發生異常,呼叫列表中排在後面的任何方法將不會被呼叫。

1

using

system;

2delegate

void d(int

x);3

classc4

910public

static

void m2(int

i)11

1415public

void m3(int

i)1619}

2021

class

test

2257 }

自從c#3.0開始,就可以使用一種新語法把實現**賦予委託:lambda表示式。只要有委託引數型別的地方,就可以使用lambda表示式。使用匿名方法的地方可以使用lambda表示式來代替,例如:

1 func< string,string > = delagate(string

para)26

可以寫成

7 func< string,string > = para=>

8

lambda表示式運算子」=>」的左邊列出了需要的引數,右邊定義了賦予lambda變數的方法的**實現。 

我們注意到,無論何時,只要我們需要引入匿名方法,我們都需要在前面加上delegate關鍵字,而且引數列表都需要型別化。lambda表示式提供了一種更為簡潔和自然的語法,而且在c#更多高階的方面中都涉及廣泛。簡而言之,我們應該用lambda表示式來替代匿名方法。 

例如:

1

public

class

person26

7 listpersonlist = new list();

89 personlist.find(delegate(person p));

10//

可以寫成

11 personlist.find(p=>p.age==12);

****

匿名委託Lambda表示式

2種形式都是宣告委託的形式 2.0以前 c 命名方法是宣告委託的唯一方法 c 2.0 之後引入匿名方法 c 3.0以及更高版本中 使用lambda表示式 取代了匿名方法 作為編寫內聯 的首選方式 匿名方法 delegate void anonymity int x anonymity m anony...

匿名函式 委託 lambda表示式 擴充套件方法

using system using system.collections.generic using system.linq using system.text namespace 匿名函式與lambda somedelegate f delegate string s f zhangfeng l...

匿名委託與Lambda表示式

通過使用匿名委託 匿名方法 使程式設計變得更加靈活,有關委託與匿名委託請參考我的前一篇blog 委託與匿名委託 繼續之前示例,如下 static void main string args worker worker new worker int result worker.handletwonum...