Exporter (0) Imprimer
Développer tout
Développer Réduire
Cet article a fait l'objet d'une traduction automatique. Déplacez votre pointeur sur les phrases de l'article pour voir la version originale de ce texte. Informations supplémentaires.
Traduction
Source

Type::MakeGenericType, méthode

Substitue les éléments d'un tableau de types aux paramètres de type de la définition du type générique actuel et retourne un objet Type qui représente le type construit résultant.

Espace de noms :  System
Assembly :  mscorlib (dans mscorlib.dll)

public:
virtual Type^ MakeGenericType(
	... array<Type^>^ typeArguments
)

Paramètres

typeArguments
Type : array<System::Type>
Tableau de types à remplacer pour les paramètres de type du type générique actuel.

Valeur de retour

Type : System::Type
Type représentant le type construit formé en substituant les éléments de typeArguments pour les paramètres de type du type générique actuel.

ExceptionCondition
InvalidOperationException

Le type actuel ne représente pas une définition de type générique. En d'autres termes, IsGenericTypeDefinition retourne la valeur false.

ArgumentNullException

typeArguments a la valeur une référence null (Nothing en Visual Basic).

ou

Tout élément de typeArguments est une référence null (Nothing en Visual Basic).

ArgumentException

Le nombre d'éléments dans typeArguments n'est pas le même que le nombre de paramètres de type dans la définition du type générique actuel.

ou

Tout élément de typeArguments ne satisfait pas les contraintes spécifiées pour le paramètre de type correspondant du type générique actuel.

ou

typeArguments contient un élément qui est un type pointeur (Type::IsPointer retourne true), un type par référence (Type::IsByRef retourne true) ou Void.

NotSupportedException

La méthode appelée n'est pas prise en charge dans la classe de base. Les classes dérivées doivent fournir une implémentation.

La méthode MakeGenericType vous permet d'écrire un code qui assigne des types spécifiques aux paramètres de type d'une définition de type générique, créant ainsi un objet Type qui représente un type construit particulier. Vous pouvez utiliser cet objet Type pour créer des instances d'exécution du type construit.

Les types construits avec MakeGenericType peuvent être ouverts. En d'autres termes, certains de leurs arguments de type peuvent être des paramètres de type de méthodes ou de types génériques englobants. Vous pouvez utiliser de tels types construits ouverts lorsque vous émettez des assemblys dynamiques. Par exemple, considérez les classes Base et Derived dans le code suivant.


generic<typename T, typename U>
    public ref class Base { };
generic<typename V>
    public ref class Derived : Base<int, V> { };


Pour générer Derived dans un assembly dynamique, il est nécessaire de construire son type de base. Pour cela, appelez la méthode MakeGenericType sur un objet Type qui représente la classe Base, à l'aide des arguments de type générique Int32 et le paramètre de type V de Derived. Comme les types et les paramètres de type générique sont représentés par des objets Type, un tableau contenant les deux peut être passé à la méthode MakeGenericType.

RemarqueRemarque

Un type construit tel que Base<int, V> est utile lors de l'émission de code, mais vous ne pouvez pas appeler la méthode MakeGenericType sur ce type, car ce n'est pas une définition de type générique. Pour créer un type construit fermé qui peut être instancié, appelez en premier lieu la méthode GetGenericTypeDefinition pour obtenir un objet Type représentant la définition de type générique, puis appelez MakeGenericType avec les arguments de type souhaités.

L'objet Type retourné par MakeGenericType est le même que le Type obtenu en appelant la méthode GetType du type construit résultant, ou la méthode GetType de tout type construit, créé à partir de la même définition de type générique, à l'aide des mêmes arguments de type.

RemarqueRemarque

Un tableau de types génériques n'est pas lui-même un type générique. Vous ne pouvez pas appeler MakeGenericType sur un type tableau tel que C<T>[] (Dim ac() As C(Of T) en Visual Basic). Pour construire un type générique fermé de C<T>[], appelez GetElementType pour obtenir la définition de type générique C<T>; appelez MakeGenericType sur la définition de type générique pour créer le type construit ; enfin, appelez la méthode MakeArrayType sur le type construit pour créer le type de tableau. Il en va de même pour les types pointeur et les types ref (ByRef en Visual Basic).

Pour obtenir la liste des conditions invariables des termes utilisés dans une réflexion générique, consultez les notes sur la propriété IsGenericType.

Types imbriqués

Si un type générique est défini à l'aide de C#, C++ ou Visual Basic, ses types imbriqués sont tous génériques. Cela est même vrai si les types imbriqués n'ont pas eux-mêmes de paramètres de type, car les trois langages incluent les paramètres de type de types englobants dans les listes de paramètre de type de types imbriqués. Considérez les classes suivantes :


generic<typename T> public ref class Outermost
{
public:
    generic<typename U> ref class Inner
    {
    public:
        generic<typename V> ref class Innermost1 {};
        ref class Innermost2 {};
    };
};


La liste de paramètres de type de la classe Inner imbriquée a deux paramètres de type, T et U, dont le premier est le paramètre de type de sa classe englobante. De la même façon, la liste de paramètres de type de la classe Innermost1 imbriquée a trois paramètres de type, T, U et V, avec T et U issus de ses classes englobantes. La classe Innermost2 imbriquée a deux paramètres de type, T et U, issus de ses classes englobantes.

Si la liste de paramètres du type englobant a plusieurs paramètres de type, tous les paramètres de type en ordre sont inclus dans la liste de paramètres de type du type imbriqué.

Pour construire un type générique à partir de la définition de type générique pour un type imbriqué, appelez la méthode MakeGenericType avec le tableau formé en concaténant les tableaux d'arguments de type de tous les types englobants, en commençant par le type générique le plus externe et en terminant par le tableau d'arguments de type du type imbriqué lui-même, s'il possède des paramètres de type propres. Pour créer une instance d'Innermost1, appelez la méthode MakeGenericType avec un tableau contenant trois types à assigner à T, U et V. Pour créer une instance d'Innermost2, appelez la méthode MakeGenericType avec un tableau contenant deux types à assigner à T et U.

Les langages propagent de cette manière les paramètres de type de types englobants afin que vous puissiez utiliser les paramètres de type d'un type englobant pour définir des champs de types imbriqués. Sinon, les paramètres de type ne seraient pas dans la portée dans les corps des types imbriqués. Il est possible de définir des types imbriqués sans propager les paramètres de type de types englobants, en émettant le code dans les assemblys dynamiques ou en utilisant l'Ilasm.exe (Assembleur IL). Considérez le code suivant pour l'assembleur MSIL :

.class public Outer<T> {
    .class nested public Inner<U> {
        .class nested public Innermost {
        }
    }
}

Dans cet exemple, il n'est pas possible de définir un champ de type T ou U dans la classe Innermost, car ces paramètres de type ne sont pas dans la portée. Le code assembleur suivant définit les classes imbriquées qui se comportent comme si elles étaient définies en C++, Visual Basic et C#:

.class public Outer<T> {
    .class nested public Inner<T, U> {
        .class nested public Innermost<T, U, V> {
        }
    }
}

Vous pouvez utiliser le Ildasm.exe (Désassembleur IL) pour examiner les classes imbriquées définies dans les langages de niveau supérieur et observer ce schéma d'affectation de noms.

L'exemple suivant utilise la méthode MakeGenericType pour créer un type construit à partir de la définition de type générique pour le type Dictionary<TKey, TValue>. Le type construit représente un Dictionary<TKey, TValue> d'objets Test avec des clés de type chaîne.


using namespace System;
using namespace System::Reflection;
using namespace System::Collections::Generic;

namespace Example
{
    public ref class Test
    {
    public:
        static void CreateConstructedType(void)
        {      
            Console::WriteLine("\r\n--- Create a constructed type"
                " from the generic Dictionary`2 type.");

            // Create a type object representing 
            // the generic Dictionary`2 type.
    	    Type^ genericType = Type::GetType(
                "System.Collections.Generic.Dictionary`2");
    	    if (genericType != nullptr)
    	    {  
    	        DisplayTypeInfo(genericType);
    	    }
    	    else
    	    {
    	        Console::WriteLine("The type is not found");
    	        return;
    	    }

            // Create an array of types to substitute for the type
            // parameters of Dictionary`2. 
            // The key is of type string, and the type to be 
            // contained in the Dictionary`2 is Test.
            array<Type^>^ typeArgs = {String::typeid, Test::typeid};
            Type^ constructedType = 
                genericType->MakeGenericType(typeArgs);
            DisplayTypeInfo(constructedType);

            // Compare the type objects obtained above to type objects
            // obtained using typeof() and GetGenericTypeDefinition().
            Console::WriteLine("\r\n--- Compare types obtained by"
                " different methods:");

    	    Type^ definedType = Dictionary<String^, Test^>::typeid;
            Console::WriteLine("\tAre the constructed types "
                "equal? {0}", definedType == constructedType);
            Console::WriteLine("\tAre the generic types equal? {0}", 
                definedType->GetGenericTypeDefinition() == genericType);
        }

    private:
        static void DisplayTypeInfo(Type^ typeToDisplay)
        {   
            Console::WriteLine("\r\n{0}", typeToDisplay);
            Console::WriteLine("\tIs this a generic type definition? "
                "{0}", typeToDisplay->IsGenericTypeDefinition);
            Console::WriteLine("\tIs it a generic type? "
                "{0}", typeToDisplay->IsGenericType);

            array<Type^>^ typeArguments = 
                typeToDisplay->GetGenericArguments();
            Console::WriteLine("\tList type arguments ({0}):", 
                typeArguments->Length);

            for each (Type^ typeArgument in typeArguments)
            {   
                Console::WriteLine("\t\t{0}", typeArgument);
            }
        }
    };
}

int main(void)
{
    Example::Test::CreateConstructedType();
}

/* This example produces the following output:

--- Create a constructed type from the generic Dictionary`2 type.

System.Collections.Generic.Dictionary`2[KeyType,ValueType]
          Is this a generic type definition? True
          Is it a generic type? True
          List type arguments (2):
                     K
                     V

System.Collections.Generic.Dictionary`2[System.String, Test]
          Is this a generic type definition? False
          Is it a generic type? True
          List type arguments (2):
                     System.String
                     Test

--- Compare types obtained by different methods:
          Are the constructed types equal? True
          Are the generic types equal? True
 */


.NET Framework

Pris en charge dans : 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Pris en charge dans : 4, 3.5 SP1

Bibliothèque de classes portable

Pris en charge dans : Bibliothèque de classes portable

.NET pour les applications du Windows Store

Pris en charge dans : Windows 8

.NET pour les applications Windows Phone

Pris en charge dans : Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (rôle principal du serveur non pris en charge), Windows Server 2008 R2 (rôle principal du serveur pris en charge avec SP1 ou version ultérieure ; Itanium non pris en charge)

Le .NET Framework ne prend pas en charge toutes les versions de chaque plateforme. Pour obtenir la liste des versions prises en charge, consultez Configuration requise du .NET Framework.

Ajouts de la communauté

AJOUTER
Microsoft réalise une enquête en ligne pour recueillir votre opinion sur le site Web de MSDN. Si vous choisissez d’y participer, cette enquête en ligne vous sera présentée lorsque vous quitterez le site Web de MSDN.

Si vous souhaitez y participer,
Afficher:
© 2014 Microsoft