多播委託與事件

2022-07-20 14:21:16 字數 3993 閱讀 8857

我們通過委託可以實現把方法作為引數,傳遞給委託執行。同樣,我們的委託也可以依次執行多個方法,此時就需要我們的多播委託了。

沒有接觸多播委託之前,我們呼叫多個方法的委託定義如下:

returnwithpara para = new returnwithpara(showid); //

當前類的方法

returnwithpara para1 = showid;//

當前類的方法

returnwithpara para2 = (i, name) => console.writeline("

編號:" + i + "

,名稱:

" + name);//

lamda表示式

returnwithpara para3 = new otherclass().showid;//

外部類的例項方法

returnwithpara para4 = otherclass.showidstatic;//

外部類的靜態方法

當使用多播委託後,我們的**如下:

//

多播委託方式:通過+=新增方法,形成方法鏈,並按順序執行

returnwithpara para = new returnwithpara(showid); //

當前類的方法

para +=showid;

para += (i, name) => console.writeline("

編號:" + i + "

,名稱:

" + name);//

lamda表示式

para += new otherclass().showid;//

外部類的例項方法

para += otherclass.showidstatic;//

外部類的靜態方法

para.invoke(21, "

張三");

多播委託方式:通過+=新增方法,形成方法鏈,invoke時按新增順序執行方法.

同樣,我們也可以通過-=給委託例項移除方法,如下所示

//

多播委託移除:通過-=給委託例項移除方法,從方法鏈的尾部開始匹配,遇到第乙個完全吻合的移除,並且只移除一次

para -=showid;

para -= (i, name) => console.writeline("

編號:" + i + "

,名稱:

" + name);//

lamda表示式

para -= new otherclass().showid;//

外部類的例項方法

para -= otherclass.showidstatic;//

外部類的靜態方法

para.invoke(22, "

李四");

注意:多播委託移除:通過-=給委託例項移除方法,從方法鏈的尾部開始匹配,遇到第乙個完全吻合的移除,並且只移除一次

以上**執行後,我們會發現

(i, name) => console.writeline(

"編號:

"+ i +

",名稱:

"+ name);和

newotherclass().showid;沒有移除成功。

這是因為:1.每個lamda表示式在編譯時都會生成乙個不同的方法,但都屬於同乙個例項。因此lamda表示式不能移除,所以不推薦lamda表示式寫法

2.new otherclass().showid不能移除是因為是兩個不同的匿名物件,所以不能移除

多播委託不能直接呼叫非同步方法(eg:para.begininvoke(22,"李四");),如果要使用非同步呼叫,可以採取下面的方法

returnwithpara para = new returnwithpara(showid); //

當前類的方法

para +=showid;

para += (i, name) => console.writeline("

編號:" + i + "

,名稱:

" + name);//

lamda表示式

para += new otherclass().showid;//

外部類的例項方法

para += otherclass.showidstatic;//

外部類的靜態方法

foreach (var item in

para.getinvocationlist())

在上述**中,我們通過para.getinvocationlist()方法獲取所有的執行方法,迴圈執行每個的非同步方法。

注意:由於多播委託執行帶返回值的多播委託時,只返回最後乙個方法的返回值,所以多播委託不適用於帶返回值的委託。

多播委託常用的場景就是觀察者模式。如下**所示

我們首先定義個cat,chicken等實體,每個實體都有乙個方法事件。cat的miao方法會引起連鎖反應,會引起雞叫,baby哭泣等等,cat類裡面定義了個委託cathander

public

class

cat

}public

action cathander;

}

在程式的上級呼叫中如下所示:

cat cat = new

cat();

cat.cathander += new

chicken().wo;

cat.cathander += new

dog().wang;

cat.cathander += new

baby().cry;

cat.cathander += new

father().roar;

cat.cathander += new

brother().turn;

cat.cathander += new

mother().run;

cat.miao();

cat.miao()執行後就會呼叫繫結了事件的多播委託cathander
使用觀察者設計模式的好處:保證了cat類的穩定,需求變更時,只需修改最上層呼叫即可,無需關注cat**

定義:多播委託的定義前面加乙個event關鍵字,如下所示,我們子啊cat裡面定義了乙個事件cathanderevent

public

event

action cathanderevent;

public

void

miaoevent()

}

上層代買呼叫執行:

cat cat = new

cat();

cat.cathanderevent += new

chicken().wo;

cat.cathanderevent += new

dog().wang;

cat.cathanderevent += new

baby().cry;

cat.cathanderevent += new

father().roar;

cat.cathanderevent += new

brother().turn;

cat.cathanderevent += new

mother().run;

cat.miaoevent();

觀察以上**,和多播委託很類似。

從以上部分介紹,我們是否感覺多播委託和事件很類似,那為什麼還要用事件呢?

事件加了許可權限制,在事件定義的外部類(或定義類的子類)中,只允許外部+=和-=。不能進行類似cat.cathanderevent=null之類的賦值,這種賦值只能在定義事件的內部類中才可以。

委託與事件的區別和聯絡:委託是乙個類,而事件是委託的乙個實體物件

事件應用很廣泛,主要包含:

1.伺服器的控制項的點選事件、下拉事件等。

3.請求級事件:經常註冊module 等等

C 多播委託與事件

1.發布 訂閱模式 委託本身是乙個更大的模式的基本單位,這個模式稱為發布 訂閱。委託的使用及其對publish subscribe模式的支援是需要學習的重點。雖然,很多問題都可以單獨用委託來實現,但是事件構造提供了額外的 封裝 使publish subscribe模式更容易實現,更不容易出錯。2.多...

委託 多播委託 event 事件

委託 多播委託 意義 多播委託有啥用呢?乙個委託例項包含多個方法,可以通過 去增加 移除方法,invoke時可以按順序執行全部動作 多播委託 任何乙個委託都是多播委託型別的子類,可以通過 去新增方法 給委託的例項新增方法,會形成方法鏈,invoke時,會按順序執行系列方法 給委託的例項移除方法,從方...

c 委託 與多播委託delegate

委託又叫匿名函式,首先我們來說為什麼要使用委託 委託到底是什麼 舉乙個例子 我想求煉表裡少於10的數的和,getsum static int getsum listlist return sum 我又想求煉表裡所有奇數的和,那麼是否是又要寫乙個函式getsum2 來求呢 static int get...