Procédures génériques dans Visual Basic

Une procédure générique, également appelée méthode générique, est une procédure définie avec au moins un paramètre de type. Cela permet au code appelant d’adapter les types de données à ses besoins chaque fois qu’il appelle la procédure.

Une procédure n’est pas générique simplement en vertu d’être définie à l’intérieur d’une classe générique ou d’une structure générique. Pour être générique, la procédure doit prendre au moins un paramètre de type, en plus des paramètres normaux qu’elle peut prendre. Une classe ou une structure générique peut contenir des procédures non génériques, et une classe, une structure ou un module non générique peut contenir des procédures génériques.

Une procédure générique peut utiliser ses paramètres de type dans sa liste normale de paramètres, dans son type de retour s’il en a un et dans son code de procédure.

Inférence de type

Vous pouvez appeler une procédure générique sans fournir d’arguments de type. Si vous l’appelez de cette façon, le compilateur tente de déterminer les types de données appropriés à passer aux arguments de type de la procédure. Il s’agit de l’inférence de type. Le code suivant montre un appel dans lequel le compilateur déduit qu’il doit passer le type String au paramètre de type t.

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

Si le compilateur ne peut pas déduire les arguments de type à partir du contexte de votre appel, il signale une erreur. Une cause possible d’une telle erreur est une incompatibilité de classement de tableau. Par exemple, supposons que vous définissez un paramètre normal en tant que tableau d’un paramètre de type. Si vous appelez la procédure générique fournissant un tableau d’un autre rang (nombre de dimensions), l’incompatibilité entraîne l’échec de l’inférence de type. Le code suivant montre un appel dans lequel un tableau à deux dimensions est passé à une procédure qui attend un tableau unidimensionnel.

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

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

Vous pouvez appeler l’inférence de type uniquement en omettant tous les arguments de type. Si vous fournissez un seul argument de type, vous devez les fournir tous.

L’inférence de type est prise en charge uniquement pour les procédures génériques. Vous ne pouvez pas appeler l’inférence de type sur des classes génériques, des structures, des interfaces ou des délégués.

Exemple

Description

L’exemple suivant définit une procédure Function générique pour rechercher un élément particulier dans un tableau. Il définit un paramètre de type et l’utilise pour construire les deux paramètres dans la liste des paramètres.

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

Commentaires

L’exemple précédent nécessite la capacité de comparer searchValue par rapport à chaque élément de searchArray. Pour garantir cette capacité, il limite le paramètre de type T pour implémenter l’interface IComparable<T>. Le code utilise la méthode CompareTo au lieu de l’opérateur =, car il n’existe aucune garantie qu’un argument de type fourni pour T prenne en charge l’opérateur =.

Vous pouvez tester la procédure findElement avec le code suivant.

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

Les appels précédents à MsgBox affichent respectivement « 0 », « 1 » et « -1 ».

Voir aussi