Des chercheurs danois et suédois en sciences informatiques et systèmes autonomes ont décortiqué la sécurité...
Nvidia se prépare à livrer la plate-forme serveur HGX-2 qui sera capable d'exploiter la puissance de 16 GPU Tesla V100...
L'EMD, une école de commerce située à Marseille ouvre à la prochaine rentrée l'école du numérique...
T
, vous pouvez écrire une seule classe qui peut être utilisée par un autre
code client sans impliquer le coût ou le risque des casts ou des opérations de boxing à l'exécution, comme illustré ici :System.Collections.Generic
.
Celles-ci doivent être utilisées chaque fois que c'est possible, à la place de classes comme ArrayList
dans l'espace de noms System.Collections
.
System.Collections.Generic
, qui contient plusieurs nouvelles classes de collection génériques.
Pour toutes les applications qui ciblent le .NET Framework version 2.0 et ultérieures, il est recommandé d'utiliser les nouvelles classes de
collection génériques plutôt que leurs équivalents non génériques, tels que ArrayList
.
Pour plus d'informations, consultez Génériques en .NET.List‹T›
fournie par
la bibliothèque de classes .NET Framework plutôt que de créer la vôtre. Le paramètre de type T
est utilisé dans plusieurs emplacements où un type concret est normalement utilisé pour indiquer
le type de l'élément stocké dans la liste. Il est utilisé de la façon suivante :AddHead
.Data
de la classe imbriquée Node
.data
de la classe imbriquée.T
est disponible pour la classe imbriquée Node
.
Quand GenericList‹T›
est instancié avec un type concret, par exemple comme un GenericList‹int›
,
chaque occurrence de T
est remplacée par int
.GenericList‹T›
pour créer une liste d'entiers. En changeant l'argument de type,
vous pouvez facilement modifier le code suivant pour créer des listes de chaînes ou tout autre type personnalisé :Object
. En créant une classe générique, vous pouvez créer une
collection qui est de type sécurisé au moment de la compilation.ArrayList
de la bibliothèque de classes .NET.
Une instance de la classe ArrayList
peut stocker n'importe quel type référence ou valeur.Object
.
Si les éléments sont des types valeur, ils doivent faire l'objet d'un boxing quand ils sont ajoutés à la liste, et d'un unboxing quand ils sont récupérés.
Les opérations de casting aussi bien que les opérations de boxing / unboxing affectent les performances.
L'effet du boxing et de l'unboxing peut être très significatif quand vous devez itérer au sein de collections volumineuses.ArrayList
effectue un cast de tous les éléments en Object
,
il n'existe aucun moyen d'empêcher le code client de procéder comme suit au moment de la compilation :int
dans
un seul ArrayList
est plus vraisemblablement une erreur de programmation, et cette erreur ne sera pas détectée avant l'exécution.ArrayList
et d'autres classes semblables ont vraiment besoin est un moyen permettant au code client de spécifier, pour chaque instance,
le type de données particulier qu'elles ont l'intention d'utiliser. Cela élimine la nécessité d'effectuer un upcast en Object
et permettrait
également au compilateur d'effectuer un contrôle de type. En d'autres termes, ArrayList
a besoin d'un paramètre de type. C'est exactement ce
que fournissent les génériques. Dans la collection List‹T›
générique, dans l'espace de noms System.Collections.Generic
, la même opération
d'ajout d'éléments à la collection ressemble à ceci :List‹T›
par rapport à ArrayList
est l'argument de type dans la déclaration et l'instanciation.
En échange de cette complexité de codage légèrement supérieure, vous pouvez créer une liste qui est non seulement plus sûre que ArrayList
,
mais également considérablement plus rapide, surtout quand les éléments de la liste sont des types valeur.GenericList‹T›
répertoriée
dans Introduction aux génériques, ne peut pas être utilisée en l'état car il ne s'agit pas vraiment d'un type, mais plutôt d'un modèle pour un type.
Pour utiliser GenericList‹T›
, le code client doit déclarer et instancier un type construit en spécifiant un argument de type à l'intérieur de crochets pointus.
L'argument de type pour cette classe particulière peut être tout type reconnu par le compilateur.
Il est possible de créer un nombre quelconque d'instances de type construit, chacune avec un argument de type différent, comme suit :GenericList‹T›
, chaque occurrence de T
dans la classe sera substituée au moment de l'exécution avec l'argument de type.
Par cette substitution, nous avons créé trois objets distincts de type sécurisé et efficaces à l'aide d'une seule définition de classe. T
comme nom de paramètre de type pour les types ayant un paramètre de type d'une seule lettre.T
.ISession
peut être appelé TSession
.Object
, qui est la classe de base par excellence de tous les types .NET.
Si le code client essaie d'instancier votre classe à l'aide d'un type qui n'est pas autorisé par une contrainte,
il en résulte une erreur de compilation. Les contraintes sont spécifiées à l'aide du mot clé contextuel where
.
Le tableau suivant liste les sept types de contrainte :Contrainte | Description |
---|---|
where T : struct |
L'argument de type doit être un type valeur. Tout type valeur, excepté Nullable‹T› .
|
where T : class |
L'argument de type doit être un type référence. Cette contrainte s'applique également à tous les types de classe, d'interface, de délégué ou de tableau. |
where T : unmanaged |
L'argument de type ne doit pas être un type référence et ne doit contenir aucun membre de type référence à tous les niveaux d'imbrication. |
where T : new() |
L'argument de type doit avoir un constructeur sans paramètre public .
Quand vous utilisez la contrainte new() avec d'autres contraintes, elle doit être spécifiée en dernier.
|
where T : ‹nom_classe_de_base› |
L'argument de type doit être la classe de base spécifiée ou en dériver. |
where T : ‹nom_interface› |
L'argument de type doit être ou implémenter l'interface spécifiée. Plusieurs contraintes d'interface peuvent être spécifiées. L'interface qui impose les contraintes peut également être générique. |
where T : U |
L'argument de type fourni pour T doit être l'argument fourni pour U ou en dériver.
|
struct
implique la contrainte new()
, mais la contrainte new()
ne peut pas être combinée avec la contrainte struct
.
La contrainte unmanaged
implique la contrainte struct
. La contrainte unmanaged
ne peut pas être combinée avec les contraintes struct
ou new()
.