進一步理解委託

2022-03-07 23:21:02 字數 2402 閱讀 2166

前面一篇文章介紹了委託的基本知識,接下來就進一步研究一下委託。

其實,剛開始覺得委託型別是乙個比較難理解的概念,怎麼也不覺得下面的"assembleiphonehandler"是乙個型別。

public

delegate

void assembleiphonehandler();

按照正常的情況,如果我們要建立乙個委託型別應該是:

public

class

assembleiphonehandler : system.multicastdelegate

但是,這種寫法是編譯不過的,會提示不能從"system.multicastdelegate"派生子類。

其實,這裡是編譯器為我們做了乙個轉換,當我們使用delegate關鍵字宣告乙個委託型別的時候,編譯器就會按照上面**片段中的方式為我們建立乙個委託型別。

知道了這些東西,對於委託型別的理解就比較容易了,通過delegate宣告的委託型別就是乙個從"system.multicastdelegate"派生出來的子類。

下面我們通過乙個例子來看看委託鏈的建立,以及呼叫列表的變化,基於前面一篇文章中的例子進行一些修改。

class

program

}

我們接下來進行一下單步除錯看看委託鏈建立的過程。

1. 當下面三句執行完成後,可以通過vs看到d1、d2和d3的詳細資訊

對於上面三個委託例項來說:

2. 通過"+="操作符來進行委託合併

這時,由於d4初始值為null,在使用"+="操作(combine方法)構造委託鏈時,將返回另外乙個引數d1,再將d1的引用賦給d4(通過"ilspy"檢視,如下圖)。也就是說,這時d4將指向d1所指向的物件。

3. 繼續執行委託合併,並檢視d4的變化

這時可以看到呼叫列表的變化,_invocationlist包含兩個元素,分別是d1和d2.

4. 最後進行一次委託合併,把d3合併到d4中

可以看到最新的d4例項中,呼叫列表已經包含了d3。

注意:由於委託是不可變的,所以這裡應該描述為,d3和d4的combine 產生了乙個新的委託例項,新的委託例項的呼叫列表是d3和d4的合併;操作完成後,d4變數將指向新的委託例項的引用。

疑問:其實在這步除錯過程中有個疑問,_invocationcount的值是3,但是_invocationlist中有四個元素,最後乙個為null,找了一下也沒發現為什麼,望高手看到幫忙解答。

所以對委託鏈建立的方法delegate.combine(delegate a, delegate b),可以進行下面的概括:

我們可以通過delegate類的靜態方法remove,從乙個委託鏈中移除乙個委託,這裡就不做演示了。

注意:當呼叫remove時,會遍歷(倒序)第乙個引數中的中的呼叫列表(_invocationlist), 找到與第二個引數的_target和_methodptr欄位相匹配的委託,並將其從委託列表中移除。

當有多個匹配的情況是,remove方法只移除第乙個匹配的委託;但是,可以通過remoeall方法來移除所有匹配的委託。

同樣對委託移除的方法delegate.remove(delegate a, delegate b),可以進行下面的概括:

通過這篇文章,進一步認識了委託型別,然後通過乙個例子觀察了委託鏈的建立以及呼叫列表的變化。

找到與委託簽名相符的方法來建立委託例項,也可以通過"+="和"-="來組合和移除委託

通過委託例項呼叫委託

進一步理解委託

前面一篇文章介紹了委託的基本知識,接下來就進一步研究一下委託。其實,剛開始覺得委託型別是乙個比較難理解的概念,怎麼也不覺得下面的 assembleiphonehandler 是乙個型別。public delegate void assembleiphonehandler 按照正常的情況,如果我們要建...

bufferedReader進一步理解

public static void main string args string mystring system.out.println 請輸入明文 bufferedreader buf new bufferedreader new inputstreamreader system.in try...

前端進一步理解

非常開心能夠在這裡作工作匯報和個人總結,這是我鼓起勇氣的結果,算是成功了一半,呵呵。從剛來公司茫然失措的菜蛋到現在稍顯成熟的菜鳥,我知道我離成功又進了一步。以下是我對前端的理解和對自己這段時間的總結 一 前端職責 前端開發是由網頁製作演變而來的,它的主要職能就是把 的介面更好地呈現給使用者,主要包括...