delegate是類型化了的函數指針,它主要應用於回調。

學習c++的對函數指針都不回陌生,它是一個保存了函數地址的變量,但除了地址,它沒有包含任何額外的信息,如參數的個數、參數類型和函數的返回地址等,所以函數指針是非類型安全的。而delegate對回調提供了類型的安全性,從而使我們在處理回調等問題的時候可以更加優美的面向對象的方式來編寫代碼,並且在CLR的內部對delegate的操作提供了許多支持(如delegate鏈表),簡化了我們常用的操作。

在使用delegate的過程中,首先要定義一個delegate的類型,如:

public delegate void SomeFunction(Object a,int i,...);

note:它是一個類的定義,可以放在任何地方,此類型定義了此delegate所接收的函數的樣式:返回void,參數列表...

然後,爲了使用,要定義類SomeFunction的一個實例:

public SomeFunction instance;

接着,我們就可以往這個delegate實例中放“符合規範”的函數(可以爲實例函數和靜態函數)。

instance +=new SomeFunction(someObject.SomeMethod);

其中someObject爲某類的一個實例,它的方面SomeMethod符合此委託的規範要求,否則將編譯報錯。

最後,可以直接調用instance實例來實現對someObject的SomeMethod的回調。

instance(...);

##########################

只是從上面的實現中,貌似看不出delegate真正存在的價值,但實際上delegate增加了對鏈的支持,我們可以象下面這樣應用:

instance +=new SomeFunction(someObject.SomeMethod);

instance +=new SomeFunction(anotherObject.anotherMethod);

...

然後調用instance(...),可以同時激發所有註冊自裏面的回調函數。

這是怎樣實現的,首先要研究delegate內在的結構,在每個delegate裏面包括了三個字段:

target ——》指向回調函數所屬的對象實例(對於實例方法來言)

method ——》指向回調函數

prev ——》指向另外一個delegate 實例

通過prev就可以比較方便的實現delegate對鏈的支持。

CLR定義了Delegate.Combine和Delegate.Remove靜態方法實現對鏈表的操作 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章