Visual Basic におけるジェネリック プロシージャ
ジェネリック プロシージャは、少なくとも 1 つの型パラメーターで定義されるプロシージャであり、ジェネリック メソッドとも呼ばれます。これを使用すると、呼び出し元のコードは、プロシージャを呼び出すたびにその要件に合わせてデータ型を調整できます。
プロシージャは、ジェネリック クラスまたはジェネリックな構造体内で定義されていることだけでジェネリックになるわけではありません。ジェネリックであるためには、プロシージャは、必要に応じて使用される通常のパラメーター以外に、少なくとも 1 つの型パラメーターを使用する必要があります。ジェネリック クラスまたはジェネリックな構造体が、非ジェネリック プロシージャを含むことも、非ジェネリックなクラス、構造体、またはモジュールが、ジェネリック プロシージャを含むこともできます。
ジェネリック プロシージャは、その型パラメーターを、その通常のパラメーター リスト、その戻り値の型があればその型、およびそのプロシージャ コードで使用できます。
型の推定
型引数を一切指定しないでジェネリック プロシージャを呼び出すことができます。この方法で呼び出す場合、コンパイラは、プロシージャの型引数に渡す適切なデータ型を決定しようとします。これは、型の推定と呼ばれます。コンパイラが String 型を型パラメーター t に渡すと推定する呼び出しを次のコードに示します。
Public Sub testSub(Of t)(ByVal arg As t)
End Sub
Public Sub callTestSub()
testSub("Use this string")
End Sub
コンパイラが呼び出しのコンテキストから型引数を推定できない場合、エラーが報告されます。このようなエラーの原因の 1 つは、配列ランクの不一致です。たとえば、通常のパラメーターを型パラメーターの配列として定義するとします。異なるランク (次元数) の配列を指定するジェネリック プロシージャを呼び出すと、不一致により型の推定が失敗します。1 次元配列を受け取るプロシージャに 2 次元配列が渡される呼び出しを次のコードに示します。
Public Sub demoSub(Of t)(ByVal arg() As t)
End Sub
Public Sub callDemoSub()
Dim twoDimensions(,) As Integer
demoSub(twoDimensions)
End Sub
型の推定は、すべての型引数を省略することによってのみ呼び出すことができます。型引数を 1 つでも指定する場合は、すべての型引数を指定する必要があります。
型の推定がサポートされるのは、ジェネリック プロシージャの場合だけです。型の推定を、ジェネリック クラス、構造体、インターフェイス、またはデリゲートで呼び出すことはできません。
例
Description
次の例では、配列内の特定の要素を検索するためのジェネリック Function プロシージャを定義しています。これは、1 つの型パラメーターを定義し、それを使用して、パラメーター リストに 2 つのパラメーターを構築します。
コード
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" が表示されます。
参照
処理手順
方法: 複数のデータ型に同一の機能を提供できるクラスを定義する (Visual Basic)
方法: ジェネリック クラスを使用する (Visual Basic)