C#中拜托的進一步懂得。本站提示廣大學習愛好者:(C#中拜托的進一步懂得)文章只能為提供參考,不一定能成為您想要的結果。以下是C#中拜托的進一步懂得正文
後面一篇文章引見了拜托的根本常識,接上去就進一步研討一下拜托。
拜托類型
其實,剛開端認為拜托類型是一個比擬難懂得的概念,怎樣也不認為上面的"AssembleIphoneHandler"是一個類型。
public delegate void AssembleIphoneHandler();
依照正常的情形,假如我們要創立一個拜托類型應當是:
public class AssembleIphoneHandler : System.MulticastDelegate
{
}
然則,這類寫法是編譯不外的,會提醒不克不及從"System.MulticastDelegate"派生子類。
其實,這裡是編譯器為我們做了一個轉換,當我們應用delegate症結字聲明一個拜托類型的時刻,編譯器就會依照下面代碼片斷中的方法為我們創立一個拜托類型。
曉得了這些器械,關於拜托類型的懂得就比擬輕易了,經由過程delegate聲明的拜托類型就是一個從"System.MulticastDelegate"派生出來的子類。
樹立拜托鏈
上面我們經由過程一個例子來看看拜托鏈的樹立,和挪用列表的變更,基於後面一篇文章中的例子停止一些修正。
class Program
{
static void Main(string[] args)
{
Apple apple = new Apple();
Foxconn foxconn = new Foxconn();
Apple.AssembleIphoneHandler d1, d2, d3, d4 = null;
d1 = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);
d2 = new Apple.AssembleIphoneHandler(foxconn.PackIphone);
d3 = new Apple.AssembleIphoneHandler(foxconn.ShipIphone);
d4 += d1;
d4 += d2;
d4 += d3;
d4();
Console.Read();
}
}
我們接上去停止一下單步驟試看看拜托鏈樹立的進程。
1. 當上面三句履行完成後,可以經由過程VS看到d1、d2和d3的具體信息
d1 = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);
d2 = new Apple.AssembleIphoneHandler(foxconn.PackIphone);
d3 = new Apple.AssembleIphoneHandler(foxconn.ShipIphone);
關於下面三個拜托實例來講:
1.挪用列表為空,所以_invocationCount為0,_invocationList為空
2._target代表創立拜托實例的辦法來自Foxconn的實例;假如是靜態辦法創立的拜托實例_target值為null
3._methodPtr代表這個辦法的獨一標識,可以懂得為句柄
4._methodBase包括創立拜托實例的辦法的信息,辦法名、前往類型等等
2. 經由過程"+="操作符來停止拜托歸並
d4 += d1;
這時候,因為d4初始值為null,在應用"+="操作(Combine辦法)結構拜托鏈時,將前往別的一個參數d1,再將d1的援用賦給d4(經由過程"ILSpy"檢查,以下圖)。也就是說,這時候d4將指向d1所指向的對象。
3. 持續履行拜托歸並,並檢查d4的變更
d4 += d2;
這時候可以看到挪用列表的變更,_invocationList包括兩個元素,分離是d1和d2.
4. 最初停止一次拜托歸並,把d3歸並到d4中
d4 += d3;
可以看到最新的d4實例中,挪用列表曾經包括了d3。
留意:因為拜托是弗成變的,所以這裡應當描寫為,d3和d4的Combine 發生了一個新的拜托實例,新的拜托實例的挪用列表是d3和d4的歸並;操作完成後,d4變量將指向新的拜托實例的援用。
疑問:其其實這步驟試進程中有個疑問,_invocationCount的值是3,然則_invocationList中有四個元素,最初一個為null,找了一下也沒發明為何,望高手看到協助解答。
所以對拜托鏈樹立的辦法Delegate.Combine(Delegate A, Delegate B),可以停止上面的歸納綜合:
1.假如A和B均為null,則前往null。
2.假如A或B一個為null而另外一個不為null,則前往不為null的拜托。
3.假如A和B均不為null,前往一個新的拜托(拜托是弗成變的),該拜托_invocationList字段為一個拜托數組,該數組中拜托的次序為:A中_invacationList所指向的拜托數組 + B中_invacationList所指向的拜托數組。
移除拜托鏈
我們可以經由過程Delegate類的靜態辦法Remove,從一個拜托鏈中移除一個拜托,這裡就不做演示了。
留意:當挪用Remove時,會遍歷(倒序)第一個參數中的中的挪用列表(_invocationList), 找到與第二個參數的_target和_methodPtr字段相婚配的拜托,並將其從拜托列表中移除。
當有多個婚配的情形是,Remove辦法只移除第一個婚配的拜托;然則,可以經由過程RemoeAll辦法來移除一切婚配的拜托。
異樣對拜托移除的辦法Delegate.Remove(Delegate A, Delegate B),可以停止上面的歸納綜合:
1.假如A為null,前往null。
2.假如B為null,前往A。
3.假如A的_invocationList為null,即不包括拜托鏈,那末假如A自己與B婚配,則前往null,不然前往A。
4.假如A的_invocationList中不包括與B婚配的拜托,則前往A。
5.假如A的_invocationList中包括與B婚配的拜托,則從鏈表中移除B,然後
6.假如A的鏈表中只剩下一個拜托,則前往該拜托。
6-1).假如A的鏈表中還剩下多個拜托,將從新構建一個新的拜托,而且新的拜托的_invocationList為A的6-2)._invocationList移除B以後的List。
總結
經由過程這篇文章,進一步熟悉了拜托類型,然後經由過程一個例子不雅察了拜托鏈的樹立和挪用列表的變更。
經由過程這兩篇文章,對拜托應當有了必定的熟悉:
1.經由過程delegate症結字聲明拜托類型
[<潤飾符>] delegate <前往類型> <拜托名> ([<形參表>])
2.找到與拜托簽名符合的辦法來創立拜托實例,也能夠經由過程"+="和"-="來組合和移除拜托
new <拜托類型名> (<辦法>)
3.經由過程拜托實例挪用拜托