徹底理解C#中的委託)

來源:互聯網
上載者:User

原文地址(http://msdn.microsoft.com/zh-cn/library/ms173172(v=VS.90).aspx)

委託是一種安全地封裝方法的類型,它與 C 和 C++ 中的函數指標類似。與 C 中的函數指標不同,委託是物件導向的、型別安全的和保險的。委託的類型由委託的名稱定義。(這可真是大水沖了龍王廟,本人以前用過C++,早說是函數指標不就明白了嘛......既然看了,就耐心地看完...)

下面的樣本聲明了一個名為 Del 的委託,該委託可以封裝一個採用字串作為參數並返回 void 的方法。

public delegate void Del(string message); 

告訴編譯器 Del 是一個指向傳回值為void、有1個string參數的函數的指標,哦不,是委託,呵呵

聲明完了類型之後,還需要給它賦值才能夠運轉的,那我們來定義一個傳回值為void、有1個string參數的函數吧

public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}

接下來,我們來執行個體化這個 Del 委託

// Instantiate the delegate.
Del handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

構造委派物件時,通常提供委託將封裝的方法的名稱或使用匿名方法。 執行個體化委託後,委託將把對它進行的方法調用傳遞給方法。 調用方傳遞給委託的參數被傳遞給方法,來自方法的傳回值(如果有)由委託返回給調用方。 這被稱為調用委託。 可以將一個執行個體化的委託視為被封裝的方法本身來調用該委託。

我來白話一下,handler是Del委託的執行個體,指向了DelegateMethod() 這個方法,因此調用handler(string)和調用DelegateMethod(string)是等價的

為什麼要這麼做?這樣一來,你可以把handler作為參數進行傳遞,可以在你需要調用的時候,在任何地方調用到DelegateMethod方法

委託類型派生自 .NET Framework 中的 Delegate 類。 委託類型是密封的,不能從 Delegate 中派生委託類型,也不可能從中派生自訂類。 由於執行個體化委託是一個對象,所以可以將其作為參數進行傳遞,也可以將其賦值給屬性。 這樣,方法便可以將一個委託作為參數來接受,並且以後可以調用該委託。 這稱為非同步回調,是在較長的進程完成後用來通知調用方的常用方法。 以這種方式使用委託時,使用委託的代碼無需瞭解有關所用方法的實現方面的任何資訊。 此功能類似於介面所提供的封裝。 有關更多資訊,請參見何時使用委託而不使用介面。

回調的另一個常見用法是定義自訂的比較方法並將該委託傳遞給排序方法。 它允許調用方的代碼成為排序演算法的一部分。 下面的樣本方法使用 Del 類型作為參數:

public void MethodWithCallback(int param1, int param2, Del callback)
{
callback("The number is: " + (param1 + param2).ToString());
}

然後可以將上面建立的委託傳遞給該方法:

MethodWithCallback(1, 2, handler);

在控制台中將收到下面的輸出:

The number is: 3

在將委託用作抽象概念時,MethodWithCallback 不需要直接調用控制台 -- 設計它時無需考慮控制台。 MethodWithCallback 的作用只是準備字串並將該字串傳遞給其他方法。 此功能特彆強大,因為委託的方法可以使用任意數量的參數。

將委託構造為封裝執行個體方法時,該委託將同時引用執行個體和方法。 除了它所封裝的方法外,委託不瞭解執行個體類型,所以只要任意類型的對象中具有與委託簽名相匹配的方法,委託就可以引用該對象。 將委託構造為封裝靜態方法時,它只引用方法。 考慮下列聲明:

public class MethodClass
{
public void Method1(string message) { }
public void Method2(string message) { }
}

加上前面顯示的靜態 DelegateMethod,現在我們有三個方法可由 Del 執行個體進行封裝。

調用委託時,它可以調用多個方法。 這稱為多路廣播。 若要向委託的方法列表(調用列表)中添加額外的方法,只需使用加法運算子或加法賦值運算子(“+”或“+=”)添加兩個委託。 例如:

 

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;

//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

此時,allMethodsDelegate 在其調用列表中包含三個方法 -- Method1、Method2 和 DelegateMethod。 原來的三個委託 d1、d2 和 d3 保持不變。 調用 allMethodsDelegate 時,將按順序調用所有這三個方法。 如果委託使用引用參數,則引用將依次傳遞給三個方法中的每個方法,由一個方法引起的更改對下一個方法是可見的。 如果任一方法引發了異常,而在該方法內未捕獲該異常,則該異常將傳遞給委託的調用方,並且不再對調用列表中後面的方法進行調用。 如果委託具有傳回值和/或輸出參數,它將返回最後調用的方法的傳回值和參數。 若要從調用列表中移除方法,請使用減法運算子或減法賦值運算子(“-”或“-=”)。 例如:

//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;

由於委託類型派生自 System.Delegate,所以可在委託上調用該類定義的方法和屬性。 例如,為了找出委託的調用列表中的方法數,您可以編寫下面的代碼:

int invocationCount = d1.GetInvocationList().GetLength(0);

在調用列表中具有多個方法的委託派生自 MulticastDelegate,這是 System.Delegate 的子類。 由於兩個類都支援 GetInvocationList,所以上面的代碼在兩種情況下都適用。

多路廣播委託廣泛用於事件處理中。 事件來源對象向登入接收該事件的接收方對象發送事件通知。 為了為事件註冊,接收方建立了旨在處理事件的方法,然後為該方法建立委託並將該委託傳遞給事件來源。 事件發生時,源將調用委託。 然後,委託調用接收方的事件處理方法並傳送事件數目據。 給定事件的委託類型由事件來源定義。 有關更多資訊,請參見事件(C# 編程指南)。

在編譯時間,對分配了兩種不同類型的委託進行比較將產生編譯錯誤。 如果委託執行個體靜態地屬於類型 System.Delegate,則允許進行比較,但在運行時將返回 false。 例如:

delegate void Delegate1();
delegate void Delegate2();
static void method(Delegate1 d, Delegate2 e, System.Delegate f)
{
// Compile-time error.
//Console.WriteLine(d == e);

// OK at compile-time. False if the run-time type of f
// is not the same as that of d.
System.Console.WriteLine(d == f);
}

轉自:http://www.cnblogs.com/zdkjob/articles/2270543.html
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.