C 委託的詳細講解

2021-10-03 10:53:25 字數 3351 閱讀 6318

委託是c#中一種型別,它的作用相當於c語言中的函式指標,它定義了方法的型別,使得可以將方法當作另乙個方法的引數來進行傳遞,這種將方法動態地賦給引數的做法,可以避免在程式中大量使用if-else(switch)語句,同時使得程式具有更好的可擴充套件性。

委託和類是同級別的,我們可以直接將delegate看成為關鍵字class,區別為class裡存放的是一系列方法,屬性,字段,事件,索引。而delegate裡存放的是一系列具有相同型別引數和返回回型別的方法的位址的位址。可以看著為儲存方法的載體。

delegate 《函式返回型別》 委託名(函式引數)

例:public delegate void mydelegate(string name);

(1) 常規例項化委託

語法:《委託名》 例項化名 = new 《委託名》(註冊函式)

注意:註冊函式不包含引數,或者可以直接將乙個註冊函式賦值給委託。 例:

mydelegate  _md = new mydelegate

(method)

;

(2)匿名方法例項化委託

語法: 《委託型別》 《例項化名》=delegate(《函式引數》); 例:

mydelegate  md =

delegate

(string s)

;

(3)使用lambda表示式例項化委託

語法:引數列 =>語句或語句塊

用法規則:

「lambda表示式」的引數數量必須和「委託」的引數數量相同;

如果「委託」的引數中包括有ref或out修飾符,則「lambda表示式」的引數列中也必須包括有修飾符;     例:

class test

static

void

main()

}

這三種方法都可以實現功能,lamda表示式只是簡化了委託的宣告,以及委託的例項化和呼叫。 從下面的例子中讓我們看看三者的區別:

class program

;//3、使用lambda表示式

mydelegate mdlambda =

(int x,

int y)

=>;}

static

intsum

(int x,

int y)

}

多播委託繼承自 delegate,即 「多路廣播委託」(multicastdelegate)。從名字就可以看出,此種委託可以像廣播一樣將影響資訊「傳播」到四面八方。多播委託類擁有乙個方法呼叫列表,呼叫委託時,它就會逐一呼叫該列表中的方法,從而實現多重影響。

在現實生活中,多播委託的例子是隨處可見的,例如某點餐的應用程式,既可以預定普通的餐飲也可以預定蛋糕、鮮花、水果等商品。在這裡委託相當於點餐平台,每乙個型別的商品可以理解為在委託上註冊的乙個方法。

多播委託的初始化可以像普通委託一樣,傳入乙個簽名相同的例項方法。同時,多播委託過載了 += 運算子和 -= 運算子,用來向其呼叫列表中新增或者刪除方法。呼叫多播委託時,方法將按照新增的順序被依次呼叫。

我們定義乙個簡單的執行加減運算的委託,並利用+=運算子和lambda表示式為該多播委託新增兩個方法:

public delegate int

adddelegate

(int a)

;adddelegate md = new adddelegate

(i =

> i +10)

;md +

= i =

> i -

10;

!!!使用委託,直接md( )就相當於使用了md. invoke()

呼叫上面的adddelegate,傳入乙個引數10:

console.

writeline(md

(10))

;

執行**,得到結果:

0
你們有疑問嗎?為什麼有兩個方法,怎麼只有乙個返回值呢?

實際上,兩個方法都被呼叫了。案例講解:

多播委託按照順序呼叫其列表中的方法。首先,引數先呼叫了 i => i + 10 函式,得到了函式返回值20。然而,委託的呼叫並沒有停止, 而是繼續呼叫剩餘的方法。然後繼續對引數呼叫 i => i - 10 函式,得到新的返回值0,上個函式的返回值被覆蓋。至此委託呼叫結束,返回最後呼叫方法的返回結果。

因此,乙個有非空返回值的多播委託通常是沒有意義的,因為只能獲得最後乙個方法的返回結果。所以通常,多播委託的返回型別為 void。

那麼對於返回型別不為空的多播委託來說,有沒有辦法得到所有方法的返回結果呢?答案是有,多播委託提供了乙個 getinvocationlist () 方法,通過它可按順序獲取並執行呼叫列表中的方法。用法舉例:

console.

writeline

("每個都呼叫:");

foreach (adddelegate f in md.

getinvocationlist()

) console.

writeline

(f.invoke(10

));

如此便可逐個得到方法的輸出結果:

每個都呼叫:

200

委託也支援泛型的使用 ,泛型委託原型:delegate 《委託名》(t1 t1,t2 t2,t3 t3…)

func委託

func委託代表著擁有返回值的泛型委託。func有一系列的過載,形式如 func,其中tresult代表委託的返回值型別,其餘均是引數型別。只有乙個t時,即func,代表該委託是無引數的。.net封裝了最多16個輸入引數的funct<>委託。

!!!若方法返回 void ,由於 void 不是資料型別,因此不能定義func委託。

action委託

action委託代表返回值為空 void 的委託,它也有一些列過載,最多擁有16個輸入引數。用法與func相同。

predicate委託

這個一般用的較少,它封裝返回值為bool型別的委託,可被func代替。

說白了,委託就是第三方,呼叫者告訴第三方要做什麼,然後呼叫者就不用管了 這個委託(第三方)就會去呼叫方法去幫你實現。

使用委託的好處:

1.相當於用方法作為另一方法引數(類似於c的函式指標)

2.在兩個不能直接呼叫的方法中作為橋梁,如:在多執行緒中的跨執行緒的方法呼叫就得用委託。

3.當不知道方法具體實現什麼時使用委託,如:事件中使用委託。

c語言詳細講解!

你知道我們申明乙個變數時象這樣int i 這個i是可能在它處重新變賦值的。如下 int i 0 i 20 這裡重新賦值了 不過有一天我的程式可能需要這樣乙個變數 暫且稱它變數 在申明時就賦乙個初始值。之後我的程式在其它任何處都不會再去重新對它賦值。那我又應該怎麼辦呢?用const const int...

C 委託與事件講解 三

protected void btnsearch click object sender,imageclickeventargs e 那他們到底表示什麼呢?在回答上面的問題之前,我們先搞懂 net framework的編碼規範 一 委託型別的名稱都應該以eventhandler結束。二 委託的原型定...

C 委託與事件講解 二

什麼是事件?event?點選事件?載入事件?一連串的模糊的概念衝擊著我們弱小的腦袋 那我們首先來看一下比較正統的感念吧 事件是類在發生其關注的事情時用來提供通知的一種方式。事件的發生一般都牽扯2個角色 事件發行者 publisher 乙個事件的發行者,也稱作是傳送者 sender 其實就是個物件,這...