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 つ指定する場合は、すべて指定する必要があります。

型の推定は、ジェネリック プロシージャでのみサポートされています。 ジェネリック クラス、構造体、インターフェイス、またはデリゲートに対して、型の推定を呼び出すことはできません。

説明

次の例では、配列内の特定の要素を探す、ジェネリック 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

コメント

前の例は、searchArray の各要素に対して searchValue を比較する必要があります。 この動作を保証するために、型パラメーター TIComparable<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" が表示されます。

関連項目