Visual Basic におけるジェネリック プロシージャ

更新 : 2007 年 11 月

ジェネリック プロシージャは、少なくとも 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

コメント

前の例では、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 におけるプロシージャ

プロシージャのパラメータと引数

参照

型リスト

パラメータの一覧