委託:讓方法能夠跟簡單對象同樣做爲參數進行傳遞,也就是將方法做爲參數進行封裝。
方法:本質就是代碼段數組
其實也好理解,目的就是爲了封裝,多態,既然簡單對象如int i能夠作爲參數傳遞,那麼語句代碼段應該也能夠做爲參數傳遞。測試
委託之於方法就像父類之於子類
委託就是一個抽象化的方法類型定義
(目的也是爲了方便方法做爲參數傳遞,這樣想,又有點泛型的感受)code
簡單對象抽象一次出現了類型
簡單類型抽象一次出現了泛型
簡單方法抽象一次出現了委託htm
委託在IL中實際上就是一個class對象
public delegate void MyDelegate(); public static void test() { MyDelegate d = null; MyDelegate d1 = new MyDelegate(obj.Method); MyDelegate d2 = new MyDelegate(obj.Method); d += d1; d += d2; }
public delegate void MyDelegate(); public static void test() { MyDelegate d = null; d += obj.Method; d += obj.Method; }
若是上述理解沒錯的話,再加上我簡單的測試了下,Add watch
兩個d,委託d的GetInvocation
是一致的,那麼所謂委託鏈跟多播委託在上述的用法上的沒區別的。blog
委託鏈包裝的方法會順序被執行,若是委託鏈中被調用的委託拋出一個異常,這樣鏈中的後續全部對象都不會被調用。事件
直接調用這個委託鏈(委託鏈自己就是個委託)委託的返回值爲非void
的話,只有最後一個返回值會被保留,以前的都捨棄。原型鏈
若需解決上述問題,經過調用Delegate.GetInvocation
方法來獲取委託鏈對象數組,顯示調用鏈中的每個委託。get
Delegate.GetInvocation
返回一個Delegate
引用構成的數組,注意是引用,數組中的每一個對象指向一個委託對象。而指向的這個委託對象又能夠有本身的委託引用數組,一直下去,造成一條委託鏈,是否是有點相似js的原型鏈
。
委託變量能夠在定義該委託變量的類外部直接調用和用=賦值,一旦向類外部公開(委託變量修飾符爲public)委託變量,何時調用這個委託變量,你是沒法控制的。
事件則不一樣,在定義事件變量的類外部只能添加或移除處理程序(方法,本質也是委託),而事件在何時,什麼條件下執行只能在定義事件變量的類內部定義。
事件可看做委託的一個特殊實例。叫實例貌似不太恰當,由於事件自己沒有方法掛載,也就是沒有實現。叫「子委託」 或許合適點,由於委託其實就是class
,那麼事件叫委託的「子類」也何嘗不可。
事件之於委託貌似又相似屬性之於字段
+= -=對應於get set
歡迎討論~
感謝閱讀~
我的公衆號: