假定您在為一家新計算機公司起草業務計劃
面對如何處理產品分發的問題
當然
您從未考慮過親自將每一件新產品交付到每位客戶的手中
相反
您會將此責任委托給像 FedEx 或 UPS 等配送服務機構
您必須事先做三個決定
該行動是什麼(交付產品)
參數是什麼(客戶地址)以及返回值是什麼(付款)
然後
當實際有一個包裹要交付時
您就可以將責任委托給某個特定的配送服務機構
在 Microsoft
NET 編程中
您會面對需要執行某種特定操作
但是無法預先知道將調用何種方法來執行該操作的情況
例如
在單擊某個按鈕時
可能需要調用某個方法
但是在設計該按鈕時
卻無法知道將調用哪個方法
您需要有一種方法來描述要調用何種方法
這正是委托派上用場的地方
在本文中
我將探索如何在 Visual Basic
NET 中使用委托
入門 委托是一種引用類型
表示帶有特定簽名和返回類型的方法
可以在該委托中封裝任何匹配的方法
另外
還可以將委托看作是對方法的引用
要了解其工作方式
我們來看一個委托解決的問題
正如您將在圖
中看到的
我將創建一個 Pair 類的簡單集合
其中有兩個對象
Pair 類創建一個名為 thePair 的私有數組
其中包括兩個成員
Public Class Pair
Private thePair(
) As Object
構造函數接受兩個對象
然後按接收順序將其添加到此內部數組中
Public Sub New(ByVal firstObject As Object
ByVal secondObject As Object)
thePair(
) = firstObject
thePair(
) = secondObject
End Sub
Pair 提供其它三種方法
Sort
ReverseSort 以及 ToString 的重寫
Sort 方法將對內部數組中的兩個對象進行排序
當然
您不希望讓 Pair 類知道對這兩個對象進行排序的測試
因為實際上您可能在 Pair 中存儲任何類型的對象(Students
Dogs
Employees
Buttons
等等)
Pair 如何才能知道如何對所有這些不同類型的對象進行排序呢?
解決方案是將責任(確定哪個對象最小)委托給對象自己
Pair 如何實現這一點?使用委托(參見圖
)
在 Pair 類中
我已經定義了一個委托以封裝(引用)比較兩個對象的方法
然後確定哪個較小(不管
較小
是如何定義的
確定的比較類都是合適的)
Public Delegate Function WhichIsSmaller( _
ByVal obj
As Object
ByVal obj
As Object) As Comparison
這是一個相當復雜的定義
讓我們來一段一段地查看這個定義
; Public 關鍵字將該委托聲明為 Pair 類的一個公共成員
; Delegate 關鍵字表示您正在創建一個委托(而不是一個方法或屬性)
; Function 關鍵字表示該委托將用於封裝一個函數(而不是一個子程序)
; WhichIsSmaller 標識符是該委托的名稱
; 括號內的值是該委托將封裝的方法的簽名
即該委托可能封裝任何接受兩個對象作為參數的函數
; 最後的關鍵字 As Comparison 是該委托可能封裝的方法的返回類型
Comparison 是一個在 Pair 類中定義的枚舉
Public Enum Comparison
theFirst =
theSecond =
End Enum
用該委托封裝的方法必須返回 Comparison
theFirst 或 Comparison
theSecond
總之
剛剛展示的語句在名為 WhichIsSmaller 的 Pair 類中定義了一個公共委托
它封裝接受兩個對象作為參數的函數並返回 Comparison 枚舉類型的一個實例
可以在該委托的實例中封裝任何匹配的方法
例如
您的 Pair 集合可能包含兩個 Student 對象
如下所示
Public Class Student
Private name As String
Public Sub New(ByVal name As String)
Me
name = name
End Sub
other Student methods here
End Class
您的 Student 類必須創建一個與 WhichIsSmaller 委托相匹配的方法
例如
您可以創建一個 WhichStudentIsSmaller 方法(參見圖
中的代碼)
該方法匹配所要求的簽名
它接受兩個對象作為參數
並且返回一個 Comparison 值
因為我的 WhichStudentIsSmaller 方法需要將這些參數用作 Student 對象
而不是作為更一般的 Object 類型
我將把這些參數強制轉換為 Student
這是類型安全的
因為我決不會用其他任何類型的參數來調用該方法
一旦我強制轉換了這兩個對象
我就可以對它們進行比較
在本例中
我將按字母順序比較它們的名稱值
並返回合適的枚舉值
Pair
Comparison
theFirst 或 Pair
Comparison
theSecond
按字母順序的比較是通過調用 String 類的共享方法 Compare 來完成的
如果按照字母表
第一個字符串排在第二個前面(s
name 的字母順序在 s
name 之前)
則 Compare 返回一個負整數值
如果按照字母表
第二個字符串排在第一個前面
則 Compare 返回一個正整數值
如果相同則返回零
其他類也能創建與 WhichIsSmaller 委托相匹配的方法
例如
我還可以創建 Dog 類
Public Class Dog
Private weight As Integer
Public Sub New(ByVal weight As Integer)
Me
weight = weight
End Sub
other Dog methods here
End Class
該 Dog 類將實現一個方法
基於重量對兩個 Dog 實例進行比較
Public Shared Function WhichDogIsSmaller( _
ByVal o
As Object
ByVal o
As Object) As parison
Dim d
As Dog = DirectCast(o
Dog)
Dim d
As Dog = DirectCast(o
Dog)
If d
weight > d
weight Then
Return Pair
Comparison
theSecond
Else
Return Pair
Comparison
theFirst
End If
End Function
現在該 Pair 類就可以創建其 Sort 方法了
它將接受一個 WhichIsSmaller 委托作為參數
Public Sub Sort(ByVal theDelegatedFunc As WhichIsSmaller)
If theDelegatedFunc(thePair(
)
thePair(
)) = _
Comparison
theSecond Then
Dim temp As Object = thePair(
)
thePair(
) = thePair(
)
thePair(
) = temp
End If
End Sub
Sort 方法通過委托來調用委托的方法
傳遞 Pair 數組的兩個成員
返回一個枚舉值
如果該值為 Comparison
theSecond
就知道第二個對象比第一個類型小
Sort 方法甚至無需知道這兩個對象的類型就可以知道這一點!然後它可以將這兩個對象顛倒過來
如果委托的方法返回 Comparison
theFirst
則無需交換
實例化委托 要對此進行測試
可以創建兩個 Student 對象
如下所示
Dim Jesse As New Student(
Jesse
)
Dim Stacey As New Student(
Stacey
)
然後將其添加到一個新的 Pair 對象中
Dim studentPair As New Pair(Jesse
Stacey)隨後
可以實例化一個 WhichIsSmaller 委托
傳遞知道如何比較這兩個 Student 對象的 Student 的匹配方法
Dim theStudentDelegate As New _
Pair
WhichIsSmaller(AddressOf Student
WhichStudentIsSmaller)
現在我可以將這個委托傳遞給 Sort 方法
以便對這個兩個學生進行排序
studentPair
Sort(theStudentDelegate)
類似地
我可以創建兩個 Dog 對象
將其添加到 Pair
並基於比較兩個 Dog 的 Dog 方法實例化一個委托
然後將該委托傳遞給 Dog 對的排序方法
如以下各行所示
make two dogs
Dim Milo As New Dog(
)
Dim Fred As New Dog(
)
store the two dogs in a Pair
Dim dogPair As New Pair(Milo
Fred)
instantiate a delegate
Dim theDogDelegate As New _
Pair
WhichIsSmaller(AddressOf Dog
WhichDogIsSmaller)
invoke Sort
pass in the delegate
dogPair
Sort(theDogDelegate)
Pair 類有一個接受相同的委托作為 Sort 的 ReverseSort
我同樣可以將您剛剛創建的 Student 和 Dog 委托傳遞給 ReverseSort
studentPair
ReverseSort(theStudentDelegate)dogPair
ReverseSort(theDogDelegate)
您可能已經猜到了
ReverseSort 的邏輯與 Sort 的邏輯相反
即
僅在比較方法返回的值指示第一個對象比第二個對象小的情況下
才交換 Pair 中的這兩項
實例方法與委托 在圖
所示示例中
封裝了 Dog 和 Student 類的共享方法
相反
可以同樣容易地將封裝的方法聲明為實例方法(即
非共享方法)
Public Comparison
WhichStudentIsSmaller(o
as Object
o
as Object)
盡管可以將該方法封裝在委托中
但是必須通過實例而不是通過類來引用它
如下所示
Dim theStudentDelegate As _
New Pair
WhichIsSmaller(AddressOf Jesse
WhichStudentIsSmaller)
盡管重復調用一個封裝了實例方法的委托比調用一個靜態方法效率更高
您還是需要一個實例來調用該方法
共享委托 中聲明委托的方法的一個缺點是
調用類 (Tester) 必須實例化所需
From:http://tw.wingwit.com/Article/Security/201401/30211.html