標籤:des style blog http color 使用
A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. The following example declares a delegate named Del that can encapsulate a method that takes a string as an argument and returns void:
(委託是一種安全地封裝方法的類型,它與 C 和 C++ 中的函數指標類似。 與 C 中的函數指標不同,委託是物件導向的、型別安全的和保險的。 委託的類型由委託的名稱定義。 下面的樣本聲明了一個名為 Del 的委託,該委託可以封裝一個採用字串作為參數並返回 void 的方法。)
public delegate void Del(string message);
A delegate object is normally constructed by providing the name of the method the delegate will wrap, or with an anonymous Method. Once a delegate is
instantiated, a method call made to the delegate will be passed by the delegate to that method. The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. This is known as invoking the delegate. An instantiated delegate can be invoked as if it were the wrapped method itself. For example:(構造委派物件時,通常提供委託將封裝的方法的名稱或使用匿名方法。 執行個體化委託後,委託將把對它進行的方法調用傳遞給方法。 調用方傳遞給委託的參數被傳遞給方法,來自方法的傳回值(如果有)由委託返回給調用方。 這被稱為調用委託。 可以將一個執行個體化的委託視為被封裝的方法本身來調用該委託。 例如:)
// Create a method for a delegate.public static void DelegateMethod(string message){ System.Console.WriteLine(message);}
// Instantiate the delegate.Del handler = DelegateMethod;// Call the delegate.handler("Hello World");
Delegate types are derived from the Delegate class in the .NET Framework. Delegate types are sealed—they cannot be derived from— and it is not possible to derive custom classes from Delegate. Because the instantiated delegate is an object, it can be passed as a parameter, or assigned to a property. This allows a method to accept a delegate as a parameter, and call the delegate at some later time. This is known as an asynchronous callback, and is a common method of notifying a caller when a long process has completed. When a delegate is used in this fashion, the code using the delegate does not need any knowledge of the implementation of the method being used. The functionality is similar to the encapsulation interfaces provide. For more information, see When to Use Delegates Instead of Interfaces.Another common use of callbacks is defining a custom comparison method and passing that delegate to a sort method. It allows the caller‘s code to become part of the sort algorithm. The following example method uses the Del type as a parameter:(委託類型派生自 .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);//(PS:注意回調這種用法)
-----------------------分割線-------------------------------------
When a delegate is constructed to wrap an instance method, the delegate references both the instance and the method. A delegate has no knowledge of the instance type aside from the method it wraps, so a delegate can refer to any type of object as long as there is a method on that object that matches the delegate signature. When a delegate is constructed to wrap a static method, it only references the method. Consider the following declarations:(將委託構造為封裝執行個體方法時,該委託將同時引用執行個體和方法。 除了它所封裝的方法外,委託不瞭解執行個體類型,所以只要任意類型的對象中具有與委託簽名相匹配的方法,委託就可以引用該對象。 將委託構造為封裝靜態方法時,它只引用方法。 考慮下列聲明:)
public class MethodClass{ public void Method1(string message) { } public void Method2(string message) { }}
Along with the static DelegateMethod shown previously, we now have three methods that can be wrapped by a Del instance.A delegate can call more than one method when invoked. This is referred to as multicasting. To add an extra method to the delegate‘s list of methods—the invocation list—simply requires adding two delegates using the addition or addition assignment operators (‘+‘ or ‘+=‘). For example:(加上前面顯示的靜態 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;
At this point allMethodsDelegate contains three methods in its invocation list—Method1, Method2, and DelegateMethod. The original three delegates, d1, d2,
and d3, remain unchanged. When allMethodsDelegate is invoked, all three methods are called in order. If the delegate uses reference parameters, the reference is passed sequentially to each of the three methods in turn, and any changes by one method are visible to the next method. When any of the methods throws an exception that is not caught within the method, that exception is passed to the caller of the delegate and no subsequent methods in the invocation list are called. If the delegate has a return value and/or out parameters, it returns the return value and parameters of the last method invoked. To remove a method from the invocation list, use the decrement or decrement assignment operator (‘-‘ or ‘-=‘). For example:(此時,allMethodsDelegate 在其調用列表中包含三個方法 -- Method1、Method2 和 DelegateMethod。 原來的三個委託 d1、d2 和 d3 保持不變。 調用 allMethodsDelegate 時,將按順序調用所有這三個方法。 如果委託使用引用參數,則引用將依次傳遞給三個方法中的每個方法,由一個方法引起的更改對下一個方法是可見的。 如果任一方法引發了異常,而在該方法內未捕獲該異常,則該異常將傳遞給委託的調用方,並且不再對調用列表中後面的方法進行調用。 如果委託具有傳回值和/或輸出參數,它將返回最後調用的方法的傳回值和參數。 若要從調用列表中移除方法,請使用減法運算子或減法賦值運算子(“-”或“-=”)。 例如:
//remove Method1allMethodsDelegate -= d1;// copy AllMethodsDelegate while removing d2Del oneMethodDelegate = allMethodsDelegate - d2;
Because delegate types are derived from System.Delegate, the methods and properties defined by that class can be called on the delegate. For example, to find the number of methods in a delegate‘s invocation list, you may write:(由於委託類型派生自 System.Delegate,所以可在委託上調用該類定義的方法和屬性。 例如,為了找出委託的調用列表中的方法數,您可以編寫下面的代碼:)
int invocationCount = d1.GetInvocationList().GetLength(0);
Delegates with more than one method in their invocation list derive from MulticastDelegate, which is a subclass of System.Delegate. The above code works in either
case because both classes support GetInvocationList.Multicast delegates are used extensively in event handling. Event source objects send event notifications to recipient objects that have registered to receive that
event. To register for an event, the recipient creates a method designed to handle the event, then creates a delegate for that method and passes the delegate to the event source. The source calls the delegate when the event occurs. The delegate then calls the event handling method on the recipient, delivering the event data. The delegate type for a given event is defined by the event source. For more, see Events (C# Programming Guide).Comparing delegates of two different types assigned at compile-time will result in a compilation error. If the delegate instances are statically of the type System.
Delegate, then the comparison is allowed, but will return false at run time. For example:(在調用列表中具有多個方法的委託派生自 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);}