我們通過委託可以實現把方法作為引數,傳遞給委託執行。同樣,我們的委託也可以依次執行多個方法,此時就需要我們的多播委託了。
沒有接觸多播委託之前,我們呼叫多個方法的委託定義如下:
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
publicclass
cat
}public
action cathander;
}
在程式的上級呼叫中如下所示:
cat cat = newcat();
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
publicevent
action cathanderevent;
public
void
miaoevent()
}
上層代買呼叫執行:
cat cat = newcat();
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...