在C#中,我們使用關(guān)鍵字delegate來定義委托,如: public delegate void MyDelegate(object obj, int x); 在進行編譯時,以上的代碼將產(chǎn)生一個類定義: public class MyDelegate : System.MulticastDelegate { public MyDelegate(Object target, IntPtr methodPtr); public void virtual Invoke(object obj, int x); // 和委托中的參數(shù)一樣. public virtual IAsyncResult BeginInvoke(object obj, int x, AsyncCallback callback, object o); public virtual void EndInvoke(IAsyncResult result); } 在以上代碼中,構(gòu)造函數(shù)中的參數(shù):target 為對象實例的引用,methodPtr為用來標識回調(diào)方法。MulticastDelegate繼承自Delegate,實際上Delegate類有四個私有字段: 1、private Object _target; 2、private IntPtr _methodPtr; 3、private IntPtr _methodPtrAux; 4、private RuntimeMethodInfo _method; 其中_target是調(diào)用方法的對象實例的引用,如果調(diào)用方法是static的,那么就不存在對象實例的引用,這時target為null。_methodPtr是用來標識要調(diào)用的方法。 在上面的MyDelegate委托中,MyDelegate的構(gòu)造構(gòu)數(shù)就是將_taget和_methodPtr進行初始化。
而 在MulticastDelegate類中,增加了一個私有字段:private MulticastDelegate _prev;這個_prev字段指向的是一個MulticastDelegate類型的引用,也就是說利用指向另一個MutlicastDelegate 類型的_prev字段來組成一個委托鏈表。 如果要向委托鏈表中增加和刪除委托,C#中使用以下語法實現(xiàn): MyDelegate myDelegate = new MyDelegate(DelegateMethod1); myDelegate += new MyDelegate(DelegateMethod2); //添加(Delegate.Combine) myDelegate -= new MyDelegate(DelegateMethod2); // 刪除(Delegate.Remove)
在 新增一個委托到委托鏈表時,MyDelegate類的構(gòu)造函數(shù)將調(diào)用基類MulticastDelegate的構(gòu)造函數(shù),將字段_target 和 _methodPtr初始化,并將MulticastDelegate的_prev字段初始化為null.在調(diào)用Remove方法時,它也會構(gòu)造一個 MyDelegate的實例,也會初始化基類的_target、_methodPtr、和_prev字段。構(gòu)造完后,Remove方法會先掃描委托鏈表, 如發(fā)現(xiàn)有和新創(chuàng)建的委托對象相等的委托對象,則將它從鏈表中刪除,如沒有找到,則不作做任何操作。
|