Partager via


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 possède un ensemble de paramètres de type (dans le cas d'une définition de type générique) ou d'arguments de type (s'il s'agit d'un type construit) qui lui est associé. Une méthode générique et une méthode ordinaire se distinguent de la même façon.

Pour comprendre comment la réflexion gère des méthodes et des types génériques, il faut savoir ce qui suit :

  • 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.

    RemarqueRemarque

    De nombreuses propriétés et méthodes de Type ont un comportement différent lorsqu'un objet Type représente un paramètre de type générique.Ces différences sont documentées dans les rubriques des propriétés et méthodes.Par exemple, consultez IsAutoClass et DeclaringType.De plus, certains membres sont valides uniquement lorsqu'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). C'est vrai aussi pour 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.

Pour comprendre ce qui suit, vous devez être familiarisé avec la terminologie des génériques et connaître par exemple la différence entre des paramètres et des arguments de type et des types construits ouverts ou fermés. Pour plus d'informations, consultez Génériques dans le .NET Framework.

Cette vue d'ensemble se compose des sections suivantes :

  • Identification d'un type ou d'une méthode générique

  • Génération de types génériques fermés

  • Examen des arguments de type et des paramètres de type

  • Invariants

  • Rubriques connexes

Identification d'un type ou d'une méthode générique

Lorsque 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. Il retourne true si le type est générique. De la même façon, lorsque vous examinez 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.

Identification d'une définition de type ou méthode 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 objet MethodInfo représente une définition de méthode générique.

Les définitions de type et de méthode génériques représentent les modèles à partir desquels vous créez des types qu'il est possible d'instancier. Les types génériques de la bibliothèque de classes du .NET Framework, par exemple Dictionary<TKey, TValue>, sont des définitions de type génériques.

Identification d'une méthode ou d'un type ouvert ou fermé

Une méthode ou un type 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 créer une instance d'un type générique uniquement s'il est fermé. La propriété Type.ContainsGenericParameters retourne true si un type est ouvert. En ce qui concerne les méthodes, la méthode MethodInfo.ContainsGenericParameters exécute la même fonction.

Retour au début

Génération de types génériques fermés

Lorsque vous avez une définition de type ou de 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.

Obtention de la définition de type ou de méthode générique

Si vous avez une méthode ou un type générique ouvert qui n'est pas une définition de méthode ou de type générique, vous ne pouvez pas créer d'instances de celui-ci, pas plus que vous ne pouvez 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.

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

Pour obtenir un exemple d'un 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

Examen des arguments de type et des paramètres de type

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

Dès que vous avez identifié un objet Type comme étant un paramètre de type, la réflexion vous permet de répondre à de nombreuses autres questions. Vous pouvez déterminer la source du paramètre de type, sa position et ses contraintes.

Paramètre de type ou argument de type

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 est 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, auquel cas il comprend un mélange d'arguments et de paramètres de type. Ainsi, dans le code suivant, la classe D dérive d'un type créé en substituant le premier paramètre de type de D au deuxième paramètre de type de B.

class B<T, U> {}
class D<V, W> : B<int, V> {}
Class B(Of T, U)
End Class
Class D(Of V, W)
    Inherits B(Of Integer, V)
End Class
generic<typename T, typename U> ref class B {};
generic<typename V, typename W> ref class D : B<int, V> {};

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

Source d'un paramètre 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 :

  • En premier lieu, 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 la 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 le paramètre de type générique appartient.

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 est sans importance.

Position d'un paramètre générique

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. Supposons, par exemple, que vous avez un objet Type qui représente le type B<int, V> de l'exemple précédent. La méthode GetGenericArguments fournit une liste d'arguments de type, et lorsque vous examinez V, vous pouvez utiliser les propriétés DeclaringMethod et DeclaringType pour découvrir son origine. Vous pouvez recourir ensuite à la propriété GenericParameterPosition pour déterminer sa position dans la liste de paramètres de type au sein de laquelle il a été défini. Dans cet exemple, V est en position 0 (zéro) dans la liste de paramètres de type dans laquelle il a été défini.

Contraintes de type de base et d'interface

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'a pas d'importance. Un élément représente une contrainte d'interface s'il s'agit d'un type interface.

Attributs de paramètres génériques

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

Covariance et contravariance

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.

Contraintes spéciales

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'existe pas de contraintes spéciales. Un paramètre de type peut être soumis à diverses contraintes, être un type référence, être un type valeur non null et avoir un constructeur par défaut.

Retour au début

Invariants

Pour obtenir un tableau des conditions invariantes des termes courants associés à la réflexion pour les types génériques, consultez Type.IsGenericType. Pour obtenir d'autres termes concernant les méthodes génériques, consultez MethodInfo.IsGenericMethod.

Retour au début

Rubriques connexes

Titre

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 de MethodInfo pour examiner des types génériques.

Génériques dans le .NET Framework

Décrit la fonctionnalité des génériques et comment elle est 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 illustrant l'utilisation de Type avec plusieurs classes Reflection pour obtenir des informations sur les constructeurs, méthodes, champs, propriétés et événements.

Retour au début