跳至內容

Delegate (CLI)

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書

委託(delegate)是一種類型安全的函數指針,用於通用語言運行庫(CLI)。在C#中,delegate是一種class,包裝了一個或多個函數指針及綁定的類實例。Delegate用來實現函數回調與事件接收(event listener)。Delegate對象可以作為參數傳遞給其他函數,以引用(referenced)封裝在delegate對象中的函數,而無需在編譯時刻就綁定被調用函數。 [1]

一旦為委託分配了函數方法,委託將與該函數方法具有完全相同的行為。 與委託的類型特徵(由返回類型和參數組成)匹配的任何方法都可以分配給該委託。

C#例子

聲明一個delegate類型,稱作SendMessageDelegate, 以一個Message類型為參數,返回類型為void:

delegate void SendMessageDelegate(Message message);

下述代碼定義了一個函數,以一個實例化的delegate類型作為形參:

void SendMessage(SendMessageDelegate sendMessageDelegateReference)
{
  // call the delegate and any other chained delegates synchronously
  sendMessageDelegateReference(new Message("hello this is a sample message"));
}

將要封裝入delegate中的一個函數的定義:

void HandleSendMessage(Message message)
{
  // the implementation for the Sender and Message classes are not relevant to this example
  Sender.Send(message);
}

函數SendMessage,以SendMessageDelegate作為委託的實例作為實參:

SendMessage(new SendMessageDelegate(HandleSendMessage));

委託實例可以封裝多個函數:

delegateType de1=fun1;
delegateType de2=fun2;
delegateType de3=de1+de2;//de3中有fun1、fun2两个函数的引用

技術實現細節

「委託」作為類,繼承自System.MulticastDelegate(抽象類)。「委託」至少0個參數,至多32個參數,可以無返回值,也可以指定返回值類型。可以認為包含:一個類對象實例的地址(Target屬性),該類的一個方法的地址(Method屬性),以及另一個「委託」實例的引用(reference)。因此引用一個「委託」對象,可能實際上引用了多個「委託」的實例。「委託」對象被調用時,依次調用裡面的多個「委託」的實例。這對於事件驅動的程序比較有用。

如果「委託」封裝了一個靜態函數,則其內部的綁定的類對象地址為null。

可以通過Delegate類的GetInvocationList()取出這些委託,並查看其Target和Method屬性,獲取所引用的方法名等信息。

泛型委託

關鍵字Action定義了無返回值的泛型委託。Action從0個參數,至多16個參數。例如:

public Action<int> cwdelegate; //定义一个委托cwdelegate,参数是int,无返回值。

關鍵字Func定義了有返回值的泛型委託。從0個參數,至多16個參數。其中最右側的泛型類型是返回值類型。

關鍵字Predict定義了返回值為bool的泛型委託。

在委託實例前,不加event,那這個委託就是一個普通的委託,可以在別的函數中調用,也可以直接用對象調用。但加上event關鍵字之後,只能用成員函數調用

用途

一個常用的用途是事件處理。CLI定義了控件的標準的事件處理函數是一個「委託」,聲明如下:

 public delegate void EventHandler(object sender, EventArgs e)

這裡第一個參數是發出該事件的控件的基類型object;後一個參數是事件數據的基類型EventArgs。以Button控件類為例,它有一個屬性Click,定義為一個EventHandle類型的delegate:

 public event EventHandle Click;

至此,我們對一個具體的button實例變量,可以給它的Click事件追加上一個或多個事件處理函數:

 this.button1.Click += new System.EventHandler(this.button1_click);

對於Visual Basic,上述語句的寫法是:

 AddHandler button1.click, AddressOf button1_Click

參考文獻

  1. ^ Sturm, Oliver. Delegate calls vastly sped up in .NET 2. 2005-09-01 [2007-09-09]. (原始內容存檔於2011-07-27). 

外部連結