委派 (Visual Basic)
委派就是參考方法的物件。 它們有時會被描述成「型別安全函式指標」(Type-Safe Function Pointer),這是因為它們與使用在其他程式語言中的函式指標類似。 但與函式指標不同的是,Visual Basic 委派是以類別 System.Delegate 為基礎的參考型別。 委派可以同時參考共用方法 (不需特定的類別執行個體即可呼叫的方法) 和執行個體方法。
委派和事件
在呼叫程序與被呼叫程序之間需要媒介的情況下,委派相當有用。 例如,您可能要引發事件的物件能夠在不同的情況下呼叫不同的事件處理常式。 不過,引發事件的物件無法事先得知事件處理常式處理特定事件的時間。 Visual Basic 會在您使用 AddHandler 陳述式時為您建立委派,讓您能夠以動態方式建立事件處理常式與事件的關聯。 委派會在 Run Time 時將呼叫轉至適當的事件處理常式。
雖然,您可以建立自己的委派,但多數情況下,Visual Basic 會為您建立委派並處理細節。 例如,Event 陳述式會將名為 <EventName>EventHandler 的委派類別,隱含定義為包含 Event 陳述式的類別的巢狀類別 (Nested Class),並與事件具有相同的簽章。 AddressOf 陳述式會以隱含方式建立委派的執行個體,而該委派會參考特定的程序。 下列兩行程式碼是對等用法。 在第一行中,您可看見 Eventhandler 執行個體的明確建立,內含當做引數傳送之 Button1_Click 方法的參考。 第二行則是用於執行相同作業的簡便方式。
AddHandler Button1.Click, New EventHandler(AddressOf Button1_Click)
' The following line of code is shorthand for the previous line.
AddHandler Button1.Click, AddressOf Me.Button1_Click
只要編譯器 (Compiler) 能夠依內容判斷委派的型別,您就可以使用簡略的方法來建立委派。
宣告使用現有委派型別的事件
在一些情況下,您可能想要宣告事件來將現有的委派型別 (Delegate Type) 當做其基礎委派使用。 如下列語法所示:
Delegate Sub DelegateType()
Event AnEvent As DelegateType
當您要傳送多個事件到相同的處理常式時,這會相當有用。
委派變數和參數
您可以在其他與事件無關的工作上使用委派,例如無限制執行緒或是需要在執行階段呼叫不同函式版本的程序。
例如,假設您有個分類廣告應用程式,其中包含具有汽車名稱的清單方塊。 廣告是依標題 (通常是汽車的型號) 排序。 當一些汽車在型號之前包括有年份時,就會發生您可能要面對的問題。 問題在於,清單方塊的內建排序功能只會依字元碼排序;它會先列出所有以日期開頭的廣告,接著才是以型號開頭的廣告。
若要解決這個問題,您可以在類別中建立一排序程序,讓它在多數的清單方塊中使用標準的字母順序排序,但能夠在 Run Time 時切換控制為汽車廣告所用的自訂排序程序。 若要這麼做,您就要在執行階段使用委派,將自訂排序程序傳遞至排序類別。
AddressOf 和 Lambda 運算式
每個委派類別會定義傳遞物件方法規格的建構函式 (Constructor)。 委派建構函式的引數必須是方法的參考或 Lambda 運算式。
若要指定方法的參考,請使用下列語法:
AddressOf [expression.]methodName
expression 在編譯時期的型別必須是包含指定名稱 (其簽章符合委派類別的簽章) 方法的類別或介面的名稱。 methodName 可以是共用方法或執行個體方法。 即使您為類別的預設方法建立委派,methodName 還是必要項。
若要指定 Lambda 運算式,請使用下列語法:
Function ([parm As type, parm2 As type2, ...]) expression
下列範例顯示用於指定委派參考的 AddressOf 和 Lambda 運算式。
Module Module1
Sub Main()
' Create an instance of InOrderClass and assign values to the properties.
' InOrderClass method ShowInOrder displays the numbers in ascending
' or descending order, depending on the comparison method you specify.
Dim inOrder As New InOrderClass
inOrder.Num1 = 5
inOrder.Num2 = 4
' Use AddressOf to send a reference to the comparison function you want
' to use.
inOrder.ShowInOrder(AddressOf GreaterThan)
inOrder.ShowInOrder(AddressOf LessThan)
' Use lambda expressions to do the same thing.
inOrder.ShowInOrder(Function(m, n) m > n)
inOrder.ShowInOrder(Function(m, n) m < n)
End Sub
Function GreaterThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
Return num1 > num2
End Function
Function LessThan(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
Return num1 < num2
End Function
Class InOrderClass
' Define the delegate function for the comparisons.
Delegate Function CompareNumbers(ByVal num1 As Integer, ByVal num2 As Integer) As Boolean
' Display properties in ascending or descending order.
Sub ShowInOrder(ByVal compare As CompareNumbers)
If compare(_num1, _num2) Then
Console.WriteLine(_num1 & " " & _num2)
Else
Console.WriteLine(_num2 & " " & _num1)
End If
End Sub
Private _num1 As Integer
Property Num1() As Integer
Get
Return _num1
End Get
Set(ByVal value As Integer)
_num1 = value
End Set
End Property
Private _num2 As Integer
Property Num2() As Integer
Get
Return _num2
End Get
Set(ByVal value As Integer)
_num2 = value
End Set
End Property
End Class
End Module
函式的簽章必須符合委派型別的簽章。 如需 Lambda 運算式的詳細資訊,請參閱 Lambda 運算式 (Visual Basic)。 如需 Lambda 運算式的更多範例和委派的 AddressOf 指派,請參閱寬鬆委派轉換 (Visual Basic)。
相關主題
標題 |
說明 |
---|---|
提供範例,顯示如何使方法與委派產生關聯,然後再透過委派叫用方法。 |
|
示範如何使用委派將某個程序傳遞至其他程序。 |
|
描述即使在簽章不同的情況下,如何將子函數與函式指派給委派或處理常式。 |
|
提供 Visual Basic 中的事件概觀。 |