看到這行代碼時,編譯器實際上會像下面這樣定義一個完整的類:代碼1-3
public class MyDelegate : System.MulticastDelegate
{
//構造器
public MyDelegate(Object aobject,IntPtr method);
//方法的原型與源代碼指定的相同
public virtual void Invoke();
//允許異步回調的方法
public virtual IAsyncResult BeginInvoke(
AsyncCallback callback, object aobject);
public virtual void EndInvoke(IAsyncResult result);
}
代碼1-3
編譯器定義的類有4個方法:一個構造器、Invoke、BeginInvoke和EndInvoke。在本章,要重點解釋構造器和Invoke方法。
事實上,可以驗證編譯器確實會自動生成這個類,具體做法就是用ILDasm.exe來查看生成的程序集(assembly),如圖1-1所示。
圖1-1 ILDasm.exe 顯示了編譯器為委托生成的元數據
在這個例子中,編譯器定義了一個類,名為MyDelegate,該類繼承自 Framework Class Library(FCL)中定義的System.MulticastDelegate 類型(所有委托類型都繼承自 MulticastDelegate)。
重要提示: System.MulticastDelegate 類繼承自 system.Delegate,後者本身繼承自System.Object。之所以有兩個委托類,是有歷史原因的,同時也是很遺憾的,FCL中本應只有一個委托類。沒有辦法,我們需要了解這兩個類,因為即使構建的所有委托類型都把MulticastDelegate作為基類,我們仍然會在個別情況下用Delegate類(而不是MulticastDelegate類)定義的方法來處理自己構建的這些委托類型。例如,Delegate 類有兩個靜態方法,分別名為 Combine 和 Remove 。這兩個方法的前面指出它們要取 Delegate 參數。因為委托類型繼承自 MulticastDelegate,後者又繼承自 Delegate,所以委托類型的實例可以被傳入這二個方法。
委托類有Public可見性,因為委托在源代碼中被聲明為Public類。我們應該知道,委托類可以在一個類型內部(即嵌套在另一個類型內)或在全局范圍內定義。簡單地說,因為委托是類,在可以定義類的任何地方,都可以定義委托。
因為所有委托類型都繼承 MulticastDelegate,所以它們都繼承了 MulticastDelegate 的字段、屬性和方法。在所有這些成員中,有3個非公共字段是最重要的。