Visual Basic 中的泛型过程
更新:2007 年 11 月
“泛型过程”,也称为“泛型方法”,是用至少一种类型参数定义的过程。调用代码每次调用该过程时,都可根据其需要修改数据类型。
一个过程之所以成为泛型过程,并不是简单地由于在泛型类或泛型结构中进行定义。若要成为泛型过程,除了可能采用的所有普通参数外,该过程还必须采用至少一种类型参数。泛型类或泛型结构中可以包含非泛型过程;而非泛型类、结构或模块中也可以包含泛型过程。
泛型过程可以在它的普通参数列表、返回类型(如果有)和过程代码中使用其类型参数。
类型推理
可以调用泛型过程,而不需提供任何类型变量。如果以这种方式调用该过程,编译器将试图确定传递到该过程类型变量中的相应数据类型。这称为“类型推理”。下面的代码演示一个调用,编译器推断它会将类型 String 传递给类型参数 t。
Public Sub testSub(Of t)(ByVal arg As t)
End Sub
Public Sub callTestSub()
testSub("Use this string")
End Sub
如果编译器无法从调用的上下文中推断出类型变量,则将报告错误。此类错误的一种可能原因是数组秩不匹配。例如,假设您将一个普通参数定义为类型参数的数组。如果所调用的泛型过程具有不同秩(维数)的数组,则秩不匹配将导致类型推理失败。下面的代码演示一个调用,其中,二维数组被传递到需要一维数组的过程中。
Public Sub demoSub(Of t)(ByVal arg() As t)
End Sub
Public Sub callDemoSub()
Dim twoDimensions(,) As Integer
demoSub(twoDimensions)
End Sub
只需省略所有类型变量,即可调用类型推理。如果您提供了一种类型变量,就必须提供所有类型变量。
只有泛型过程才支持类型推理。无法对泛型类、泛型结构、泛型接口或泛型委托调用类型推理。
示例
说明
下面的示例定义了泛型 Function 过程,用于查找数组中的特定元素。它定义一个类型参数,并用该类型参数在参数列表中构造两个参数。
代码
Public Function findElement(Of T As IComparable) _
(ByVal searchArray As T(), ByVal searchValue As T) As Integer
If searchArray.GetLength(0) > 0 Then
For i As Integer = 0 To searchArray.GetUpperBound(0)
If searchArray(i).CompareTo(searchValue) = 0 Then Return i
Next i
End If
Return -1
End Function
注释
在上例中,需要能够将 searchValue 与 searchArray 中的每个元素进行比较。为保证具有此能力,上例约束类型参数 T 实现 IComparable<T> 接口。代码使用 CompareTo 方法取代 = 运算符,这是因为无法保证为 T 提供的类型变量支持 = 运算符。
可以用下面的代码测试 findElement 过程。
Public Sub tryFindElement()
Dim stringArray() As String = {"abc", "def", "xyz"}
Dim stringSearch As String = "abc"
Dim integerArray() As Integer = {7, 8, 9}
Dim integerSearch As Integer = 8
Dim dateArray() As Date = {#4/17/1969#, #9/20/1998#, #5/31/2004#}
Dim dateSearch As Date = Microsoft.VisualBasic.DateAndTime.Today
MsgBox(CStr(findElement(Of String)(stringArray, stringSearch)))
MsgBox(CStr(findElement(Of Integer)(integerArray, integerSearch)))
MsgBox(CStr(findElement(Of Date)(dateArray, dateSearch)))
End Sub
以前对 MsgBox 的调用分别显示“0”、“1”和“-1”。