關於C#委託

來源:互聯網
上載者:User

  前段時間閑來無事,隨便在網上逛,誰知一不小心看到了這篇文章。感覺有必要瞭解下所以就轉了下來一塊分享下。。

  1.委託概述 
委託是C#中新加入的一個類型,可以把它想作一個和Class類似的一種類型,和使用類相似,使用一個委託時,需要兩個步驟,首先你要定義一個委託,就像是定義一個類一樣;然後,你可以建立一個或多個該委託的執行個體。 
定義一個委託的文法是這樣的: 
[public/protected/private] delegate returnType delegateName(paramtype param1,…) 
這是我自己寫的,看起來好像有點怪怪的,我來解釋一下,private/protected/private是限定詞,就不多說了,delegate是申 明一個委託的關鍵詞,returnType是一個傳回型別,delegateName是一個你給委託起的名字,你可以寫任何一個你喜歡的名 字,paramtype param1…這個是參數列表。說了這麼多可能看起來還是不是很好理解,我是這樣認為的,實用點來講,委託定義就是在一個函數定義中間加入一個 delegate的關鍵詞。它的作用類似於你申明一個類: 
public class ClassName {…} 
建立一個委託的執行個體: 
[public/protected/private] delegateName deleInstanceName = new delegateName(MethodName) 
這個類似於執行個體化一個類,public ClassName instancename = new ClassName(…),這裡有個要注意的地方,即MethodName方法要和delegateName的簽名一致。什麼是簽名一致,就是說 MethodName的參數列表,傳回值要分別和returnType、(paramtype param1,…)一致。舉個例子來說明下: 
public delegate string DelegateDemo(string name, int age); 
比如我們如上定義了一個委託,就寫法來說,其實就是在函數 string DelegateDemo(string name, int age)前面加了一個delegate的關鍵字,下面我們來用建立一個函數: 
public string AgentDemo(string name, int age) 

string rev = “”; 
… 
return rev; 

這個函數是做參數傳遞給一個DelegateDemo執行個體的,接下來建立一個DelegateDemo的執行個體: 
DelegateName instanceDemo = new DelegateName(AgentDemo); 
這時要說到一致了,即AgentDemo和聲明委託時的DelegateDemo(我們姑且將delegate去掉)這兩個函數的傳回值,參數列表要相同。終於說完了,不知道看的人明不明白。 
接下來,我們可以使用這個委託了(調用一個委託),如下: 
string name = “cshape”; 
int age = 20; 
instanceDemo(name, age); 
當instanceDemo執行時,會執行AgentDemo函數,instanceDemo相當於C裡的一個函數指標,現在這個指標指向AgentDemo的函數入口地址。 
2.多點委託 
前面提到的委託都只包含對一個方法的調用,如果需要調用多個方法,需要多次顯示的調用這個委託,我們還有另的選擇,我們可以讓一個委託中包含多個方法,這樣我們一次顯示調用委託,就可以按照順序連續的調用多個方法。看下面的例子: 
public delegate void MultiDelegate(string name); 
public void AgentDemo1(string str) 

Console.WriteLine(str + “this is AgentDemo1\n”); 


public void AgentDemo2(string s) 

Console.WriteLine(s + “this is AgentDemo2\n”); 


MultiDelegate multiDemo = new MultiDelegate(AgentDemo1); 
multiDemo += new MultiDelegate(AgentDemo2); 
multiDemo(“multiDemo test :”); 

輸出的結果應該是: 
multiDemo test :this is AgentDemo1 
mutliDemo test :this is AgentDemo2 

可以看到我們一次顯示的調用一個委託,它順序的(按照你添加方法的順序)執行了方法AgentDemo1和AgentDemo2。這裡要注意的有幾點: 
● 委託支援 +=,-=這樣的運算子,對應為添加或去掉一個方法 
● 多點委託不可以定義有傳回值,因為無法處理多個方法的傳回值,所以如果要使用多點委託,應該用void,否則你的編譯會返回一個錯誤 
● 多點委託不建議你的參數列表中有OUT的類型,這樣只會out最後一個方法的值,其他的值會丟失。 
3.委託的理解 
首先申明,這隻是我舉的一個例子,目的是協助理解委託的過程,其中很多地方都經不起推敲,望大家知悉。言歸正傳,
你想要吃飯, 
但是自己又不會做(委託方不知道實現細節), 
你計劃找個飯店,叫個回鍋肉飯(定義了一個委託) 
你決定找常去的那家叫做A的飯店(執行個體化一個委託) 
你打電話給A飯店(委託調用) 
A飯店給你做好了你的回鍋肉飯(代理函數工作) 
飯來了,真好。 

4.委託的使用時機 
當你需要把一個方法傳送給其他方法時,可以考慮使用委託。好像不是很好理解,也可以這樣說,當你確定要處理一件事,但又不能確定處理方法時,可以考慮用委託。其實單獨的說委託的應用好像有點牽強,委託更多的是在事件中的應用。 
5.一個委託的例子 
我用兩個類來做這個例子,一個類,我稱它為委託方,一個類我稱它為代理方,代碼如下: 
using System; 

namespace Visen.Demo.Delegate 

///<summary> 
/// StartUp 委託示範中的程式入口,含委託方。 
///</summary> 
class StartUp 

#region公用的方法 

#region應用程式的主進入點。 
///<summary> 
///應用程式的主進入點。 
///</summary> 
[STAThread] 
static void Main(string[] args) 

Console.WriteLine("This is a delegate demo\n"); 

Visen.Demo.Delegate.Agent ag = new Agent(); 

//定義一個委託類型的對象 
OutMessage singleDele = new OutMessage(ag.ShowMessage); 
OutMessage deleStaticMeth = new OutMessage(Agent.SShowMessage); 

//定義一個多點委託 
OutMessage MultiDele = new OutMessage(ag.ShowMessage); 
MultiDele += new OutMessage(Agent.SShowMessage); 

singleDele(" delegate instance singleDele"); 
deleStaticMeth(" delegate instance deleStaticMeth"); 
MultiDele(" this is a MultiDele"); 
Console.Read(); 

#endregion應用程式的主進入點。 

#endregion公用的方法 

#region私用的欄位 
///<summary> 
///定義一個委託類型 
///</summary> 
private delegate void OutMessage(string msg); 
#endregion私人的欄位 



下面是代理方: 
using System; 

namespace Visen.Demo.Delegate 

///<summary> 
/// Agent 類為委託者的代理方,處理委託者委託的事務。 
///</summary> 
public class Agent 

#region公用的方法 

#region空的建構函式 
///<summary> 
///空的建構函式 
///</summary> 
public Agent() 


#endregion空的建構函式 

#region顯示一條資訊到控制台,一個類成員函數作為代理方 
///<summary> 
///顯示一條資訊到控制台,一個類成員函數作為代理方 
///</summary> 
///<param name="msg">顯示內容</param> 
public void ShowMessage(string msg) 

Console.WriteLine("Method ShowMessage out:" + msg + "\n"); 

#endregion顯示一條資訊到控制台,一個類成員函數作為代理方 

#region顯示一條資訊到控制台,一個類靜態函數作為代理方 
///<summary> 
///顯示一條資訊到控制台,一個類靜態函數作為代理方 
///</summary> 
///<param name="msg">顯示資訊</param> 
public static void SShowMessage(string msg) 

Console.WriteLine("static Method SShowMessage out:" + msg + "\n"); 

#endregion顯示一條資訊到控制台,一個類靜態函數作為代理方 

#endregion公用的方法 


輸出為: 
This is a delegate demo 

Method ShowMessage out: delegate instance singleDele 

static Method SShowMessage out: delegate instance deleStaticMeth 

Method ShowMessage out: this is a MultiDele 

static Method SShowMessage out: this is a MultiDele 

可見:方法函數可以是類成員函數,也可以是一個靜態成員,只要和委託的簽名相同就可以了。 

有錯的地方,請大家批評指正,謝謝!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.