程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中拜托的進一步懂得

C#中拜托的進一步懂得

編輯:C#入門知識

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.經由過程拜托實例挪用拜托

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved