Cet article a fait l’objet d’une traduction automatique. Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez également afficher le texte anglais dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte traduit.
Traduction
Anglais

Type::MakeGenericType méthode (array<Type^>^)

 

Date de publication : novembre 2016

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.

Exception Condition
InvalidOperationException

Le type actuel ne représente pas une définition de type générique. Autrement dit, IsGenericTypeDefinition retourne false.

ArgumentNullException

typeArguments a la valeur null.

ou

Tout élément de typeArguments est null.

ArgumentException

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

ou

Un élément de typeArguments ne répond pas aux 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 by-ref (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.

Le MakeGenericType méthode vous permet d’écrire du 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 Type objet qui représente un type construit particulier. Vous pouvez utiliser cette Type objet pour créer des instances d’exécution du type construit.

Types construits avec MakeGenericType peuvent être ouverts, autrement dit, certains de leurs arguments de type peuvent être de placer des méthodes génériques ou les types des paramètres de type. Vous pouvez utiliser ces 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 des Derived dans un assembly dynamique, il est nécessaire de construire son type de base. Pour ce faire, appelez le MakeGenericType méthode sur un Type objet représentant la classe Base, à l’aide des arguments de type générique Int32 et le paramètre de type V de Derived. Étant donné que les types et les paramètres de type générique sont représentés par Type des objets, un tableau contenant les deux peut être passé à la MakeGenericType (méthode).

System_CAPS_noteRemarque

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

Le Type objet retourné par MakeGenericType est identique à la Type obtenu en appelant le GetType méthode des résultats de type construit, ou la GetTypeméthode de n’importe quel construite de type qui a été créé à partir de la même définition de type générique à l’aide des mêmes arguments de type.

System_CAPS_noteRemarque

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>; appeler MakeGenericType sur la définition de type générique pour créer le type construit ; et enfin appeler le MakeArrayType méthode sur le type construit pour créer le type de tableau. Est de même des types pointeur et ref types (ByRef en Visual Basic).

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

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 vrai même si les types imbriqués n’ont leur propre, aucun paramètre de type, car les trois langages incluent les paramètres de type de types englobants dans les listes de paramètres 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 imbriquée Inner possède deux paramètres de type, T et U, le premier est le paramètre de type de sa classe englobante. De même, la liste de paramètres de type de la classe imbriquée Innermost1 a trois paramètres de type, T, U, et V, avec T et U provenant de ses classes englobantes. La classe imbriquée Innermost2 possède deux paramètres de type, T et U, lesquelles viennent de ses classes englobantes.

Si la liste des paramètres du type englobant a plusieurs paramètres de type, tous les paramètres de type dans l’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 le MakeGenericType méthode avec le tableau formé en concaténant les tableaux argument de type des types englobants, à compter de type générique à l’extérieur et se terminant par le tableau de l’argument de type type lui-même, s’il a des paramètres de type de son propre. Pour créer une instance de Innermost1, appelez le MakeGenericType méthode avec un tableau contenant trois types à assigner à T, U et V. Pour créer une instance de Innermost2, appelez le MakeGenericType méthode avec un tableau contenant deux types à assigner à T et U.

Les langages propagent les paramètres de type des types englobants de cette façon afin de pouvoir utiliser les paramètres de type d’un type englobant pour définir des champs de types imbriqués. Dans le cas contraire, les paramètres de type ne peuvent pas être dans la portée au sein des instances 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 des assemblys dynamiques ou en utilisant le Ilasm.exe (IL Assembler). Prenons 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 la Ildasm.exe (IL Disassembler) 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 le MakeGenericType pour créer un type construit à partir de la définition de type générique pour la Dictionary<TKey, TValue> type. Représente le type construit un Dictionary<TKey, TValue> de Test objets 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
 */

Plateforme Windows universelle
Disponible depuis 8
.NET Framework
Disponible depuis 2.0
Bibliothèque de classes portable
Pris en charge dans : plateformes .NET portables
Silverlight
Disponible depuis 2.0
Silverlight pour Windows Phone
Disponible depuis 7.0
Windows Phone
Disponible depuis 8.1
Retour au début
Afficher: