首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

CLR 筆記:委托深度解析與實戰技巧

     編輯:關於.NET

委托核心特性

  1. 型別安全:編譯期檢測錯誤(反射則為型別不安全)。
  2. 方法指標:不區分 static 與 instance 方法。
  3. 定義位置:委托定義在類別外部,與其使用的方法平級。

協變與反協變

委托允許引用類型的協變(回傳類型:方法可衍生自委托)與反協變(參數類型:委托可衍生自方法)。範例:

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);
}

MulticastDelegate 關鍵欄位

欄位類型說明
_targetSystem.Object靜態方法為 null;實例方法為實例物件。對外表現為 Target 屬性
_methodPtrSystem.IntPtr內部整數,標識回呼方法。對外表現為 Method 屬性(已轉為 MemberInfo)
_invocationListSystem.Object通常為 null;委托鏈中形成委托物件陣列

利用 Target 與 Method 屬性可檢查委托是否參考特定型別的實例方法、回呼方法是否為特定名稱。

委托鏈:回呼多個方法

Delegate.Combine 與 Delegate.Remove 靜態方法(C# 對應 +=/-=)。單一委托時 _invocationList 為 null;多個委托形成鏈結陣列。void 型委托依序執行;有回傳值的委托返回最後一個委托的回傳值。

GetInvocationList() 處理異常

若鏈中某方法拋出異常,後續委托不會執行。使用 GetInvocationList() 取得委托陣列,逐一 try-catch 可確保所有委托皆被呼叫。

反射與委托:CreateDelegate / DynamicInvoke

編譯期不知使用哪個委托或參數時使用反射。CreateDelegate 多載支援靜態/實例方法;DynamicInvoke 執行期傳遞參數陣列。

匿名方法:優雅的委托語法

  1. 直接使用回呼函式作為參數,無需建構委托物件(編譯器自動推斷)。
  2. 不需定義回呼方法(匿名方法由此而生)。
  3. 不需指定回呼方法參數(不使用參數時可省略)。
  4. 回呼方法中可使用外部變數(閉包)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved