Types génériques en Visual Basic

Mise à jour : novembre 2007

Un type générique est un élément de programmation unique qui s'adapte pour exécuter les mêmes fonctionnalités pour différents types de données. Lorsque vous définissez une classe ou une procédure générique, vous ne devez pas définir une version distincte pour chaque type de données pour lequel vous souhaitez exécuter ces fonctionnalités.

On pourrait comparer cet élément de programmation à un tournevis à têtes amovibles interchangeables. Vous pouvez examiner la vis que vous devez serrer et sélectionner la tête la mieux adaptée (fendue, en croix, en étoile). Quelle que soit la tête insérée dans le manche du tournevis, vous exécutez toujours la même fonction : vous serrez une vis.

Tournevis configuré comme un outil générique

Diagramme d'un tournevis défini en tant qu'outil générique

Lorsque vous définissez un type générique, vous devez le paramétrer avec un ou plusieurs types de données. Cela permet au code d'utilisation d'adapter les types de données à ses exigences. Votre code peut déclarer plusieurs éléments de programmation différents à partir de l'élément générique, agissant chacun sur un jeu différent de types de données. Mais les éléments déclarés exécutent tous la même logique, quels que soient les types de données qu'ils utilisent.

Par exemple, vous souhaitez peut-être créer et utiliser une classe de file d'attente qui utilise un type de données spécifique, par exemple String. Vous pouvez déclarer cette classe à partir de System.Collections.Generic.Queue<T>, comme indiqué dans l'exemple suivant.

Public stringQ As New System.Collections.Generic.Queue(Of String)

Vous pouvez maintenant utiliser stringQ pour travailler exclusivement avec des valeurs String. Étant donné que stringQ est spécifique à String au lieu d'être généralisé pour les valeurs Object, aucune liaison tardive ou conversion de type n'est possible. Cela permet de réduire le délai d'exécution et les erreurs d'exécution.

Pour plus d'informations sur l'utilisation d'un type générique, consultez Comment : utiliser une classe générique.

Exemple d'une classe générique

L'exemple suivant présente une définition squelette d'une classe générique.

Public Class classHolder(Of t)
    Public Sub processNewItem(ByVal newItem As t)
        Dim tempItem As t
        ' Insert code that processes an item of data type t.
    End Sub
End Class

Dans le précédent squelette, t est un paramètre de type, c'est-à-dire un espace réservé pour un type de données que vous fournissez lors de la déclaration de la classe. À tout autre endroit de votre code, vous pouvez déclarer diverses versions de classHolder en fournissant divers types de données pour t. L'exemple suivant illustre ces deux déclarations.

Public integerClass As New classHolder(Of Integer)
Friend stringClass As New classHolder(Of String)

Les instructions précédentes déclarent des classes construites dans lesquelles un type spécifique remplace le paramètre de type. Ce remplacement est propagé partout dans le code de la classe construite. L'exemple suivant montre à quoi ressemblera la procédure processNewItem dans integerClass.

Public Sub processNewItem(ByVal newItem As Integer)
    Dim tempItem As Integer
    ' Inserted code now processes an Integer item.
End Sub

Pour un exemple plus complet, consultez Comment : définir une classe qui fournisse des fonctionnalités identiques pour différents types de données.

Éléments de programmation disponibles

Vous pouvez définir et utiliser des classes, des structures, des interfaces, des procédures et des délégués génériques. Notez que le .NET Framework définit plusieurs classes, structures et interfaces génériques qui représentent des éléments génériques couramment utilisés. L'espace de noms System.Collections.Generic fournit des dictionnaires, des listes, des files d'attente et des piles. Avant de définir votre propre élément générique, vérifiez s'il est déjà disponible dans System.Collections.Generic.

Les procédures ne sont pas des types, mais vous pouvez définir et utiliser des procédures génériques. Consultez Procédures génériques dans Visual Basic.

Avantages des types génériques

Un type générique sert de base de déclaration de plusieurs éléments de programmation différents, chacun utilisant un type de données spécifique. Les alternatives à un type générique sont :

  1. un type unique utilisant le type de données Object ;

  2. un ensemble de versions spécifiques au type du type, chaque version étant individuellement codée et utilisant un type de données spécifique tel que String, Integer ou un type défini par l'utilisateur tel que customer.

Un type générique présente les avantages suivants par rapport à ces alternatives :

  • Sécurité de type. Les types génériques appliquent une vérification de type au moment de la compilation. Les types basés sur Object acceptent n'importe quel type de données, et vous devez écrire le code pour vérifier si un type de données d'entrée est acceptable. Avec les types génériques, le compilateur peut intercepter les incompatibilités de type avant l'exécution.

  • Performances. Les types génériques ne doivent pas effectuer de conversion box et unbox des données, car chacun d'eux est spécialisé pour un type de données. Les opérations basées sur Object doivent effectuer une conversion box des types de données d'entrée pour les convertir en Object et effectuer une conversion unbox des données destinées à la sortie. Les conversions boxing et unboxing réduisent les performances.

    Les types basés sur Object sont également à liaison tardive, ce qui signifie que l'accès à leurs membres requiert un code supplémentaire au moment de l'exécution. Cela réduit également les performances.

  • Consolidation du code. Le code d'un type générique doit être défini une seule fois. Un ensemble de versions spécifiques au type d'un type doit répliquer le même code dans chaque version, la seule différence étant le type de données spécifique pour cette version. Avec les types génériques, les versions spécifiques au type sont toutes générées à partir du type générique d'origine.

  • Réutilisation du code. Le code qui ne dépend pas d'un type de données particulier peut être réutilisé avec divers types de données, s'il est générique. Vous pouvez généralement le réutiliser même avec un type de données que vous n'avez pas prévu initialement.

  • Prise en charge IDE. Lorsque vous utilisez un type construit déclaré à partir d'un type générique, l'environnement de développement intégré (IDE) offre une plus grande prise en charge lorsque vous développez votre code. Par exemple, IntelliSense™ peut vous indiquer les options spécifiques au type pour un argument à un constructeur ou une méthode.

  • Algorithmes génériques. Les algorithmes abstraits qui sont indépendants du type se prêtent bien aux types génériques. Par exemple, une procédure générique qui trie des éléments à l'aide de l'interface IComparable peut être utilisée avec un type de données qui implémente IComparable.

Contraintes

Bien que le code d'une définition de type générique doive être aussi indépendant du type que possible, certaines fonctionnalités doivent être requises pour tout type de données fourni à votre type générique. Par exemple, si vous souhaitez comparer deux éléments à des fins de tri ou de classement, leur type de données doit implémenter l'interface IComparable. Vous pouvez appliquer cette exigence en ajoutant une contrainte au paramètre de type.

Exemple d'une contrainte

L'exemple suivant présente une définition squelette d'une classe avec une contrainte qui exige que l'argument de type implémente IComparable.

Public Class itemManager(Of t As IComparable)
    ' Insert code that defines class members.
End Class

Si le code suivant essaie de construire une classe de itemManager en fournissant un type qui n'implémente pas IComparable, le compilateur signale une erreur.

Types de contraintes

Votre contrainte peut spécifier les éléments requis suivants selon n'importe quelle combinaison :

  • L'argument de type doit implémenter une ou plusieurs interfaces

  • L'argument de type doit être du type d'une classe ou hériter d'une classe au plus

  • L'argument de type doit exposer un constructeur sans paramètre accessible au code qui crée des objets à partir de celui-ci

  • L'argument de type doit être un type référence ou un type valeur

Si vous devez imposer plusieurs exigences, vous utilisez une liste de contraintes séparée par des virgules et mise entre accolades ({ }). Pour exiger un constructeur accessible, vous incluez le mot clé New (Visual Basic) dans la liste. Pour exiger un type référence, vous incluez le mot clé Class (Visual Basic) ; pour exiger un type valeur, vous incluez le mot clé Structure (Visual Basic).

Pour plus d'informations sur les contraintes, consultez Liste de types.

Exemple de plusieurs contraintes

L'exemple suivant présente une définition squelette d'une classe générique avec une liste de contraintes sur le paramètre de type. Dans le code qui crée une instance de cette classe, l'argument de type doit implémenter les interfaces IComparable et IDisposable, être un type référence et exposer un constructeur sans paramètre accessible.

Public Class thisClass(Of t As {IComparable, IDisposable, Class, New})
    ' Insert code that defines class members.
End Class

Termes importants

Les types génériques présentent et utilisent les termes suivants :

  • Type générique. Définition d'une classe, structure, interface, procédure ou délégué pour laquelle vous fournissez au moins un type de données lors de sa déclaration.

  • Paramètre de type. Dans une définition de type générique, espace réservé pour un type de données fourni lors de la déclaration du type.

  • Argument de type. Type de données spécifique qui remplace un paramètre de type lorsque vous déclarez un type construit d'un type générique.

  • Contrainte. Condition sur un paramètre de type qui restreint l'argument de type que vous pouvez lui fournir. Une contrainte peut exiger que l'argument de type implémente une interface particulière, soit ou hérite d'une classe particulière, contienne un constructeur sans paramètre accessible ou soit un type référence ou un type valeur. Vous pouvez associer ces contraintes, mais vous pouvez spécifier une classe au plus.

  • Type construit Classe, structure, interface, procédure ou délégué déclaré à partir d'un type générique en fournissant des arguments de type pour ses paramètres de type.

Voir aussi

Tâches

Dépannage des types de données

Concepts

Types de données en Visual Basic

Caractères de type

Types valeur et types référence

Référence

Liste des types de données (Visual Basic)

Of

As

Object, type de données

Autres ressources

Implémentation des types de données

Conversions de type en Visual Basic