Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez aussi afficher la version anglaise dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte.
Traduction
Anglais

Réflexion et types génériques

 

Du point de vue de la réflexion, la différence entre un type générique et un type ordinaire est qu'un type générique est associé à un ensemble de paramètres de type (s'il s'agit d'une définition de type générique) ou d'arguments de type (s'il s'agit d'un type construit). Une méthode générique diffère d'une méthode ordinaire de la même façon. 

Deux éléments essentiels permettent de comprendre comment la réflexion gère les types et méthodes génériques :

  • Les paramètres de type des définitions de type générique et des définitions de méthode générique sont représentés par des instances de la classe Type.

    System_CAPS_noteRemarque

    De nombreuses propriétés et méthodes de Type ont un comportement différent quand un objet Type représente un paramètre de type générique. Ces différences sont documentées dans les rubriques de la propriété et de la méthode. Par exemple, consultez IsAutoClass et DeclaringType. Par ailleurs, certains membres sont valides uniquement quand un objet Type représente un paramètre de type générique. Par exemple, consultez GetGenericTypeDefinition.

  • Si une instance de Type représente un type générique, elle inclut un tableau de types qui représentent les paramètres de type (pour les définitions de type générique) ou les arguments de type (pour les types construits). Il en est de même d'une instance de la classe MethodInfo qui représente une méthode générique.

La réflexion fournit des méthodes de Type et MethodInfo qui permettent d'accéder au tableau des paramètres de type et de déterminer si une instance de Type représente un paramètre de type ou un type réel.

Pour obtenir un exemple de code illustrant les méthodes présentées ici, consultez Comment : examiner et instancier des types génériques avec la réflexion.

La discussion suivante suppose que vous connaissez la terminologie des génériques, par exemple, la différence entre les paramètres et les arguments de type et entre les types construits ouverts ou fermés. Pour plus d'informations, consultez Génériques dans le .NET Framework.

Cette vue d'ensemble comprend les sections suivantes :

Quand vous utilisez la réflexion pour examiner un type inconnu, représenté par une instance de Type, utilisez la propriété IsGenericType pour déterminer si le type inconnu est générique. Elle retourne true si le type est générique. De la même façon, quand vous examiner une méthode inconnue, représentée par une instance de la classe MethodInfo, utilisez la propriété IsGenericMethod pour déterminer si la méthode est générique.

Utilisez la propriété IsGenericTypeDefinition pour déterminer si un objet Type représente une définition de type générique et utilisez la méthode IsGenericMethodDefinition pour déterminer si un MethodInfo représente une définition de méthode générique.

Les définitions de type et de méthode génériques sont les modèles à partir desquels les types instanciables sont créés. Les types génériques dans la bibliothèque de classes .NET Framework, tels que Dictionary<TKey, TValue>, sont des définitions de type générique.

Un type ou une méthode générique est fermé si des types instanciables ont été substitués à tous ses paramètres de type, y compris tous les paramètres de type de tous les types englobants. Vous pouvez uniquement créer une instance d'un type générique s'il est fermé. La propriété Type.ContainsGenericParameters renvoie true si un type est ouvert. Pour les méthodes, la méthode MethodInfo.ContainsGenericParameters a la même fonction.

Retour au début

Une fois que vous avez une définition de type ou méthode générique, utilisez la méthode MakeGenericType pour créer un type générique fermé ou la méthode MakeGenericMethod pour créer un MethodInfo pour une méthode générique fermée.

Si vous avez un type ou une méthode générique ouvert qui n'est pas une définition de type ou méthode générique, vous ne pouvez pas créer d'instances de ce type et vous ne pouvez pas fournir les paramètres de type manquants. Vous devez avoir une définition de type ou de méthode générique. Utilisez la méthode GetGenericTypeDefinition pour obtenir la définition de type générique ou la méthode GetGenericMethodDefinition pour obtenir la définition de méthode générique.

Par exemple, si vous avez un objet Type représentant Dictionary<int, string> (Dictionary(Of Integer, String) en Visual Basic) et que vous voulez créer le type Dictionary<string, MyClass>, vous pouvez utiliser la méthode GetGenericTypeDefinition pour obtenir un Type représentant Dictionary<TKey, TValue>, puis utiliser la méthode MakeGenericType pour produire un Type représentant Dictionary<int, MyClass>.

Pour obtenir un exemple de type générique ouvert qui n'est pas un type générique, consultez « Paramètre de type ou argument de type » plus loin dans cette rubrique.

Retour au début

Utilisez la méthode Type.GetGenericArguments pour obtenir un tableau d'objets Type qui représentent les paramètres ou les arguments de type d'un type générique, et utilisez la méthode MethodInfo.GetGenericArguments pour faire de même pour une méthode générique.

Dès que vous savez qu'un objet Type représente un paramètre de type, la réflexion peut répondre à de nombreuses autres questions. Vous pouvez déterminer la source du paramètre de type, sa position et ses contraintes.

Pour déterminer si un élément particulier du tableau est un paramètre ou un argument de type, utilisez la propriété IsGenericParameter. La propriété IsGenericParameter a la valeur true si l'élément est un paramètre de type.

Un type générique peut être ouvert sans être une définition de type générique, dans ce cas, il comprend un mélange d'arguments de type et de paramètres de type. Par exemple, dans le code suivant, la classe D dérive d'un type créé en substituant le premier paramètre de type D au deuxième paramètre de type B.

class B<T, U> {} class D<V, W> : B<int, V> {}

Si vous obtenez un objet Type représentant D<V, W> et utilisez la propriété BaseType pour obtenir son type de base, le type B<int, V> résultant est ouvert, mais n'est pas une définition de type générique.

Un paramètre de type générique peut provenir du type que vous examinez, d'un type englobant ou d'une méthode générique. Vous pouvez déterminer la source du paramètre de type générique comme suit :

  • Tout d'abord, utilisez la propriété DeclaringMethod pour déterminer si le paramètre de type vient d'une méthode générique. Si la valeur de propriété n'est pas une référence null (Nothing en Visual Basic), la source est une méthode générique.

  • Si la source n'est pas une méthode générique, utilisez la propriété DeclaringType pour déterminer le type générique auquel appartient le paramètre de type générique.

Si le paramètre de type appartient à une méthode générique, la propriété DeclaringType retourne le type qui a déclaré la méthode générique, ce qui n'est pas pertinent.

Dans de rares cas, il est nécessaire de déterminer la position d'un paramètre de type dans la liste de paramètres de type de la classe de déclaration. Par exemple, supposons que vous ayez un objet Type représentant le type B<int, V> de l'exemple précédent. La méthode GetGenericArguments vous donne la liste des arguments de type et, quand vous examinez V, vous pouvez utiliser les propriétés DeclaringMethod et DeclaringType pour découvrir d'où il vient. Vous pouvez ensuite utiliser la propriété GenericParameterPosition afin de déterminer sa position dans la liste de paramètres de type dans laquelle il a été défini. Dans cet exemple, V se trouve à la position 0 (zéro) dans la liste de paramètres de type dans laquelle il a été défini.

Utilisez la méthode GetGenericParameterConstraints pour obtenir la contrainte de type de base et les contraintes d'interface d'un paramètre de type. L'ordre des éléments du tableau n'est pas significatif. Un élément représente une contrainte d'interface s'il s'agit d'un type d'interface.

La propriété GenericParameterAttributes obtient une valeur GenericParameterAttributes qui indique l'écart (covariance ou contravariance) et les contraintes spéciales d'un paramètre de type.

Pour déterminer si un paramètre de type est covariant ou contravariant, appliquez le masque GenericParameterAttributes.VarianceMask à la valeur GenericParameterAttributes retournée par la propriété GenericParameterAttributes. Si le résultat est GenericParameterAttributes.None, le paramètre de type est invariant. Consultez Covariance et contravariance dans les génériques.

Pour déterminer les contraintes spéciales d'un paramètre de type, appliquez le masque GenericParameterAttributes.SpecialConstraintMask à la valeur GenericParameterAttributes retournée par la propriété GenericParameterAttributes. Si le résultat est GenericParameterAttributes.None, il n'y a aucune contrainte spéciale. Un paramètre de type peut être contraint à être un type de référence, un type de valeur qui n'autorise pas les valeurs null et à avoir un constructeur par défaut.

Retour au début

Pour obtenir un tableau des conditions invariantes pour les termes courants dans la réflexion pour les types génériques, consultez Type.IsGenericType. Pour obtenir des termes supplémentaires relatifs aux méthodes génériques, consultez MethodInfo.IsGenericMethod.

Retour au début

Title

Description

Comment : examiner et instancier des types génériques avec la réflexion

Montre comment utiliser les propriétés et méthodes de Type et MethodInfo pour examiner des types génériques.

Génériques dans le .NET Framework

Décrit la fonctionnalité des génériques et sa prise en charge dans le .NET Framework.

Comment : définir un type générique avec l'émission de réflexion

Montre comment utiliser l'émission de réflexion pour générer des types génériques dans des assemblys dynamiques.

Affichage des informations de type

Décrit la classe Type et fournit des exemples de code qui montrent comment utiliser Type avec diverses classes de réflexion pour obtenir des informations sur les constructeurs, les méthodes, les champs, les propriétés et les événements.

Afficher: