委托允許引用類型的協變(回傳類型:方法可衍生自委托)與反協變(參數類型:委托可衍生自方法)。範例:
delegate object MyCallBack(FileStream fs);
string SomeOtherMethod(Stream s) { }
可將 SomeOtherMethod 繫結至 MyCallBack。
宣告 public delegate string TestDele(int intTest); 等價於:
public class TestDele : System.MulticastDelegate {
public TestDele(object target, IntPtr method);
public virtual string Invoke(int intTest);
public virtual IAsyncResult BeginInvoke(int intTest, AsyncCallback cb, object state);
public virtual string EndInvoke(IAsyncResult result);
}
| 欄位 | 類型 | 說明 |
|---|---|---|
| _target | System.Object | 靜態方法為 null;實例方法為實例物件。對外表現為 Target 屬性 |
| _methodPtr | System.IntPtr | 內部整數,標識回呼方法。對外表現為 Method 屬性(已轉為 MemberInfo) |
| _invocationList | System.Object | 通常為 null;委托鏈中形成委托物件陣列 |
利用 Target 與 Method 屬性可檢查委托是否參考特定型別的實例方法、回呼方法是否為特定名稱。
Delegate.Combine 與 Delegate.Remove 靜態方法(C# 對應 +=/-=)。單一委托時 _invocationList 為 null;多個委托形成鏈結陣列。void 型委托依序執行;有回傳值的委托返回最後一個委托的回傳值。
若鏈中某方法拋出異常,後續委托不會執行。使用 GetInvocationList() 取得委托陣列,逐一 try-catch 可確保所有委托皆被呼叫。
編譯期不知使用哪個委托或參數時使用反射。CreateDelegate 多載支援靜態/實例方法;DynamicInvoke 執行期傳遞參數陣列。