Generische Prozeduren in Visual Basic

Eine generische Prozedur, auch als generische Methode bezeichnet, ist eine Prozedur, die mit mindestens einem Typparameter definiert ist. Dadurch kann der aufrufende Code die Datentypen bei jedem Aufruf der Prozedur an seine Anforderungen anpassen.

Eine Prozedur ist nicht generisch, nur weil sie innerhalb einer generischen Klasse oder einer generischen Struktur definiert wird. Um generisch zu sein, muss die Prozedur mindestens einen Typparameter zusätzlich zu den üblichen Parametern verwenden. Eine generische Klasse oder Struktur kann nichtgenerische Prozeduren enthalten, und eine nichtgenerische Klasse, Struktur oder ein nichtgenerisches Modul kann generische Prozeduren enthalten.

Eine generische Prozedur kann ihre Typparameter in ihrer üblichen Parameterliste, in ihrem Rückgabetyp, falls sie über einen verfügt, und in ihrem Prozedurcode verwenden.

Typableitung

Sie können eine generische Prozedur aufrufen, ohne irgendwelche Typargumente anzugeben. Wenn Sie sie auf diese Weise aufrufen, versucht der Compiler, die geeigneten Datentypen zu ermitteln, die an die Typargumente der Prozedur übergeben werden sollen. Dieser Vorgang wird als Typrückschluss bezeichnet. Der folgende Code zeigt einen Aufruf, in dem der Compiler ableiten soll, dass er den Typ String an den Typparameter tübergeben soll.

Public Sub testSub(Of t)(ByVal arg As t)
End Sub
Public Sub callTestSub()
    testSub("Use this string")
End Sub

Wenn der Compiler die Typargumente nicht aus dem Kontext Ihres Aufrufs ableiten kann, meldet er einen Fehler. Eine mögliche Ursache für einen solchen Fehler ist ein Arrayrangkonflikt. Stellen Sie sich beispielsweise vor, dass Sie einen normalen Parameter als Array eines Typparameters definieren. Wenn Sie die generische Prozedur aufrufen und dabei ein Array mit einem anderen Rang (Anzahl der Dimensionen) angeben, führt die Nichtübereinstimmung dazu, dass der Typrückschluss fehlschlägt. Der folgende Code zeigt einen Aufruf, in dem ein zweidimensionales Array an eine Prozedur übergeben wird, die ein eindimensionales Array erwartet.

Public Sub demoSub(Of t)(ByVal arg() As t)
End Sub

Public Sub callDemoSub()
    Dim twoDimensions(,) As Integer
    demoSub(twoDimensions)
End Sub

Sie können den Typrückschluss nur aufrufen, indem Sie alle Typargumente weglassen. Wenn Sie ein Typargument angeben, müssen Sie alle angeben.

Der Typrückschluss wird nur für generische Prozeduren unterstützt. Sie können keinen Typrückschluss für generische Klassen, Strukturen, Schnittstellen oder Delegaten aufrufen.

Beispiel

Beschreibung

Im folgenden Beispiel wird eine generische Function-Prozedur definiert, um ein bestimmtes Element in einem Array zu finden. Sie definiert einen Typparameter und verwendet ihn, um die beiden Parameter in der Parameterliste zu erstellen.

Code

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

Kommentare

Für das vorherige Beispiel ist es erforderlich, searchValue mit den einzelnen Elementen von searchArray vergleichen zu können. Damit das funktioniert, wird der Typparameter T auf die Implementierung der IComparable<T>-Schnittstelle eingeschränkt. Der Code verwendet die CompareTo-Methode anstelle des =-Operators, da es keine Garantie dafür gibt, dass ein für T angegebenes Typargument den =-Operator unterstützt.

Sie können die findElement-Prozedur mit dem folgenden Code testen.

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

Die vorherigen Aufrufe von MsgBox zeigen jeweils „0“, „1“, und „-1“ an.

Siehe auch