委派演義(3) -- 回歸基本定義

前兩篇插科打諢的胡說八道了一堆東西,就算你本來不知道委派為何物也應該不會這麼害怕看這個主題了,所以得來真的講講硬底子的玩意兒,回顧一下關於委派所應該知道的基本知識。

       前兩篇插科打諢的胡說八道了一堆東西,就算你本來不知道委派為何物也應該不會這麼害怕看這個主題了,所以得來真的講講硬底子的玩意兒,回顧一下關於委派所應該知道的基本知識。

 

       委派的名詞定義

       在 MSDN 文件庫中關於委派的說明其實有點分散,因為我記憶力越來越差,所以就在這邊整理一下。

       (1) 在 [委派 (Visual Basic)]:

       委派就是參考方法的物件。 它們有時會被描述成「型別安全函式指標」(Type-Safe Function Pointer),這是因為它們與使用在其他程式語言中的函式指標類似。 但與函式指標不同的是,Visual Basic 委派是以類別 System.Delegate 為基礎的參考型別。 委派可以同時參考共用方法 (不需特定的類別執行個體即可呼叫的方法) 和執行個體方法。

 

       (2) 在 [委派 (C# 程式設計手冊)]:

       委派是定義方法簽章的型別。 當您執行個體化委派時,可以將其執行個體與任何具有相容簽章的方法產生關聯。 您可以透過委派執行個體來叫用 (Invoke) 或呼叫方法。

       任何來自可存取的類別 (Class) 或結構 (Struct) 且與委派簽章 (由傳回型別和參數所構成) 相符的方法,都可以指派給該委派。 此方法可以是靜態或執行個體方法 (Instance Method)。 如此即可用程式設計的方式變更方法呼叫,也可將新的程式碼外掛到現有的類別中。 只要您知道委派的簽章為何,即可指派自己的方法。

 

       (3) 在 [EventHandler 委派]:

       委派是一種定義簽章的型別,簽章指的就是方法的傳回值型別和參數清單型別。 您可以使用委派型別 (Delegate Type) 宣告變數,這個變數可以參考和委派有著相同簽章的任何方法。

 

       (4) 在 [ 一般型別系統 ]:

       委派是參考型別,用途與 C++ 中的函式指標類似。 委派是用於 .NET Framework 中的事件處理常式和回呼函式。 不同於函式指標,委派更具安全性、可以驗證,而且是型別安全 (Type Safe) 的。 委派型別可以代表具有相容簽章的執行個體方法或靜態方法。

       所有的委派都繼承自 System.MulticastDelegate,該項則繼承自 System.Delegate。 C#、Visual Basic 和 C++ 語言並不允許從這些型別繼承, 而是提供關鍵字以宣告委派。

 

       不看還好,一看完全弄糊塗,上面囉哩囉唆一大堆最主要的重點是要告訴大家『委派是一種定義簽章的型別,而且它是個參考型別』,請特別注意型別兩個字,但是我覺得 Visual Basic 文件中的說法有點令人糢糊,因為它前面講『委派就是參考方法的物件』;後面又講了一句『Visual Basic 委派是以類別 System.Delegate 為基礎的參考型別』。那『簽章』又是什麼東西?這邊所謂的簽章意指兩件事 (1) 傳入方法的參數數量、順序與型別定義 (2) 方法回傳值的型別定義。在一般的狀況下我們通常會讓方法與委別型別的簽章相符 (也就是一模一樣),但是這不是絕對要一樣,關於這點以後再說,這系列文大部份的例子都會遵循簽章相符的原則來寫。

 

       圖解委派型別宣告

       在[ 委派演義(2) -- 多重委派與桃谷六仙 ] 一開始我談了委派宣告這件事,這邊重新拆解一次說明整段程式的個別意義。

(1) Visual Basic

Declare01

 

Declare02

 

(2) C#

Declare03

 

Declare04

 

       看圖說故事應該很容易了吧,宣告委派型別就是如此容易,然後你就可以拿這個委派型別去瞎弄了。

 

       委派執行個體是怎麼生出來的?

       這邊先講一個名詞叫『委派變數』,當你用一個委派型別宣告一個變數的時候,該變數就稱為委派變數,它的行為跟一般使用類別宣告的變數很類似 (有點像廢話,因為它也是個參考型別)。

 

(1) Visual Basic

Declare05

 

(2) C#

Declare06

 

       和一般參考型別相同,當你用上面的方式宣告委派變數時它並未指向任何執行個體,所以此時它是 Nothing / null,這不奇怪,不過這邊要強調的是『變數是變數;執行個體是執行個體』,變數僅是指向執行個體,變數本身並非該執行個體。

 

       比較特別的是它產生執行個體的方法,通常以下三種方式都會配置一個新的委派執行個體出來

       (1) 利用建構式:委派型別的建構式很有趣,很容易弄糊塗,因為感覺上在 Visual Basic 是用委派產生委派;但在 C# 像是用方法產生委派。不管如何,其實它就是加入方法的參考到委派執行個體中。

Dim x1 As XHandler = New XHandler(AddressOf 張無忌)

 

XHandler x1 = new XHandler(張無忌);

 

       (2) 指派方法參考給委派變數:這也就是[委派演義(1) -- 從倚天屠龍記看委派] 的用法。

 

       (3) 加入方法參考給委派變數:在 [委派演義(2) -- 多重委派與桃谷六仙 ] 的用法。這就是 MulticastDelegate 的內部機制了,當你加一個方法參考進到一個指向 Nothing / null 的委派變數時的時候就會為這個委派變數建立一個執行個體。

 

       這一篇主要在說明各種名詞,所以要分清楚委派型別委派變數委派執行個體的不同;另外則是如何宣告委派型別委派執行個體的產生方式。有沒有覺得委派其實還滿平易近人的?