Type.MakeGenericType(Type[]) Type.MakeGenericType(Type[]) Type.MakeGenericType(Type[]) Type.MakeGenericType(Type[]) Method

Definizione

Sostituisce gli elementi di una matrice di tipi ai parametri di tipo della definizione di tipo generico corrente e restituisce un oggetto Type che rappresenta il tipo costruito risultante.Substitutes the elements of an array of types for the type parameters of the current generic type definition and returns a Type object representing the resulting constructed type.

public:
 virtual Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public virtual Type MakeGenericType (params Type[] typeArguments);
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
Public Overridable Function MakeGenericType (ParamArray typeArguments As Type()) As Type

Parametri

typeArguments
Type[]

Matrice di tipi con cui sostituire i parametri di tipo del tipo generico corrente.An array of types to be substituted for the type parameters of the current generic type.

Restituisce

Oggetto Type che rappresenta il tipo costruito ottenuto sostituendo i parametri di tipo del tipo generico corrente con gli elementi di typeArguments.A Type representing the constructed type formed by substituting the elements of typeArguments for the type parameters of the current generic type.

Eccezioni

Il tipo corrente non rappresenta una definizione di tipo generico,The current type does not represent a generic type definition. Ciò significa che IsGenericTypeDefinition restituisce false.That is, IsGenericTypeDefinition returns false.

typeArguments è null.typeArguments is null.

-oppure--or- Qualsiasi elemento di typeArguments è null.Any element of typeArguments is null.

Il numero di elementi in typeArguments non è uguale al numero di parametri di tipo nella definizione di tipo generico corrente.The number of elements in typeArguments is not the same as the number of type parameters in the current generic type definition.

-oppure--or- Qualsiasi elemento di typeArguments non soddisfa i vincoli specificati per il parametro di tipo corrispondente del tipo generico corrente.Any element of typeArguments does not satisfy the constraints specified for the corresponding type parameter of the current generic type.

-oppure--or- typeArguments contiene un elemento che è un tipo di puntatore (IsPointer restituisce true), un tipo by-ref (IsByRef restituisce true) o Void.typeArguments contains an element that is a pointer type (IsPointer returns true), a by-ref type (IsByRef returns true), or Void.

Il metodo richiamato non è supportato nella classe base.The invoked method is not supported in the base class. Le classi derivate devono fornire un'implementazione.Derived classes must provide an implementation.

Esempi

Nell'esempio seguente viene usato MakeGenericType il metodo per creare un tipo costruito dalla definizione di tipo generico per Dictionary<TKey,TValue> il tipo.The following example uses the MakeGenericType method to create a constructed type from the generic type definition for the Dictionary<TKey,TValue> type. Il tipo costruito rappresenta un Dictionary<TKey,TValue> oggetto Test di oggetti con chiavi di stringa.The constructed type represents a Dictionary<TKey,TValue> of Test objects with string keys.

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
 */
using System;
using System.Reflection;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        Console.WriteLine("\r\n--- Create a constructed type from the generic Dictionary type.");

        // Create a type object representing the generic Dictionary 
        // type, by omitting the type arguments (but keeping the 
        // comma that separates them, so the compiler can infer the
        // number of type parameters).      
        Type generic = typeof(Dictionary<,>);
        DisplayTypeInfo(generic);

        // Create an array of types to substitute for the type
        // parameters of Dictionary. The key is of type string, and
        // the type to be contained in the Dictionary is Test.
        Type[] typeArgs = { typeof(string), typeof(Test) };

        // Create a Type object representing the constructed generic
        // type.
        Type constructed = generic.MakeGenericType(typeArgs);
        DisplayTypeInfo(constructed);

        // 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 t = typeof(Dictionary<String, Test>);
        Console.WriteLine("\tAre the constructed types equal? {0}", t == constructed);
        Console.WriteLine("\tAre the generic types equal? {0}", 
            t.GetGenericTypeDefinition() == generic);
    }

    private static void DisplayTypeInfo(Type t)
    {
        Console.WriteLine("\r\n{0}", t);

        Console.WriteLine("\tIs this a generic type definition? {0}", 
            t.IsGenericTypeDefinition);

        Console.WriteLine("\tIs it a generic type? {0}", 
            t.IsGenericType);

        Type[] typeArguments = t.GetGenericArguments();
        Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
        foreach (Type tParam in typeArguments)
        {
            Console.WriteLine("\t\t{0}", tParam);
        }
    }
}

/* This example produces the following output:

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

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

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
 */
Imports System.Reflection
Imports System.Collections.Generic

Public Class Test
    Public Shared Sub Main()
        Console.WriteLine(vbCrLf & "--- Create a constructed type from the generic Dictionary type.")

        ' Create a type object representing the generic Dictionary 
        ' type, by omitting the type arguments (but keeping the 
        ' comma that separates them, so the compiler can infer the
        ' number of type parameters).
        Dim generic As Type = GetType(Dictionary(Of ,))
        DisplayTypeInfo(generic)

        ' Create an array of types to substitute for the type
        ' parameters of Dictionary. The key is of type string, and
        ' the type to be contained in the Dictionary is Test.
        Dim typeArgs() As Type = { GetType(String), GetType(Test) }

        ' Create a Type object representing the constructed generic
        ' type.
        Dim constructed As Type = generic.MakeGenericType(typeArgs)
        DisplayTypeInfo(constructed)

        ' Compare the type objects obtained above to type objects
        ' obtained using GetType() and GetGenericTypeDefinition().
        Console.WriteLine(vbCrLf & "--- Compare types obtained by different methods:")

        Dim t As Type = GetType(Dictionary(Of String, Test))
        Console.WriteLine(vbTab & "Are the constructed types equal? " _
            & (t Is constructed))
        Console.WriteLine(vbTab & "Are the generic types equal? " _ 
            & (t.GetGenericTypeDefinition() Is generic))
    End Sub

    Private Shared Sub DisplayTypeInfo(ByVal t As Type)
        Console.WriteLine(vbCrLf & t.ToString())

        Console.WriteLine(vbTab & "Is this a generic type definition? " _ 
            & t.IsGenericTypeDefinition)

        Console.WriteLine(vbTab & "Is it a generic type? " _ 
            & t.IsGenericType)

        Dim typeArguments() As Type = t.GetGenericArguments()
        Console.WriteLine(vbTab & "List type arguments ({0}):", _
            typeArguments.Length)
        For Each tParam As Type In typeArguments       
            Console.WriteLine(vbTab & vbTab & tParam.ToString())
        Next
    End Sub
End Class

' This example produces the following output:
'
'--- Create a constructed type from the generic Dictionary type.
'
'System.Collections.Generic.Dictionary'2[TKey,TValue]
'        Is this a generic type definition? True
'        Is it a generic type? True
'        List type arguments (2):
'                TKey
'                TValue
'
'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

Commenti

Il MakeGenericType metodo consente di scrivere codice che assegna tipi specifici ai parametri di tipo di una definizione di tipo generico, creando in tal modo Type un oggetto che rappresenta un determinato tipo costruito.The MakeGenericType method allows you to write code that assigns specific types to the type parameters of a generic type definition, thus creating a Type object that represents a particular constructed type. È possibile utilizzare questo Type oggetto per creare istanze della fase di esecuzione del tipo costruito.You can use this Type object to create run-time instances of the constructed type.

I tipi costruiti MakeGenericType con possono essere aperti, ovvero alcuni degli argomenti di tipo possono essere parametri di tipo per l'inclusione di metodi o tipi generici.Types constructed with MakeGenericType can be open, that is, some of their type arguments can be type parameters of enclosing generic methods or types. È possibile utilizzare questi tipi costruiti aperti quando si creano assembly dinamici.You might use such open constructed types when you emit dynamic assemblies. Si considerino, ad esempio Base , Derived le classi e nel codice riportato di seguito.For example, consider the classes Base and Derived in the following code.

generic<typename T, typename U>
    public ref class Base { };
generic<typename V>
    public ref class Derived : Base<int, V> { };
public class Base<T, U> { }
public class Derived<V> : Base<int, V> { }
Public Class Base(Of T, U)
End Class
Public Class Derived(Of V)
    Inherits Base(Of Integer, V)
End Class

Per generare Derived in un assembly dinamico, è necessario creare il relativo tipo di base.To generate Derived in a dynamic assembly, it is necessary to construct its base type. A tale scopo, chiamare il MakeGenericType metodo su un Type oggetto che rappresenta la Baseclasse, usando gli argomenti Int32 di tipo generico e il V parametro Deriveddi tipo da.To do this, call the MakeGenericType method on a Type object representing the class Base, using the generic type arguments Int32 and the type parameter V from Derived. Poiché i Type MakeGenericType tipi e i parametri di tipo generico sono entrambi rappresentati da oggetti, è possibile passare al metodo una matrice contenente entrambi.Because types and generic type parameters are both represented by Type objects, an array containing both can be passed to the MakeGenericType method.

Nota

Un tipo costruito, ad Base<int, V> esempio, è utile per la creazione di codice, ma non MakeGenericType è possibile chiamare il metodo su questo tipo perché non è una definizione di tipo generico.A constructed type such as Base<int, V> is useful when emitting code, but you cannot call the MakeGenericType method on this type because it is not a generic type definition. Per creare un tipo costruito chiuso di cui è possibile creare un'istanza, chiamare GetGenericTypeDefinition prima il metodo per Type ottenere un oggetto che rappresenta la definizione di tipo MakeGenericType generico e quindi chiamare con gli argomenti di tipo desiderati.To create a closed constructed type that can be instantiated, first call the GetGenericTypeDefinition method to get a Type object representing the generic type definition and then call MakeGenericType with the desired type arguments.

L' Type oggetto restituito da MakeGenericType GetType GetType corrisponde a quello ottenutochiamandoilmetododeltipocostruitorisultanteoppureilmetododiqualsiasitipocostruitocreatodallostessogenericoType definizione del tipo utilizzando gli stessi argomenti di tipo.The Type object returned by MakeGenericType is the same as the Type obtained by calling the GetType method of the resulting constructed type, or the GetType method of any constructed type that was created from the same generic type definition using the same type arguments.

Nota

Una matrice di tipi generici non è a sua volta un tipo generico.An array of generic types is not itself a generic type. Non è possibile MakeGenericType chiamare su un tipo di matrice C<T>[] ,Dim ac() As C(Of T) ad esempio (in Visual Basic).You cannot call MakeGenericType on an array type such as C<T>[] (Dim ac() As C(Of T) in Visual Basic). Per costruire un tipo generico chiuso da C<T>[], chiamare GetElementType per ottenere la definizione C<T>di tipo generico; MakeGenericType chiamare sulla definizione di tipo generico per creare il tipo costruito e infine chiamare il MakeArrayType metodo su tipo costruito per creare il tipo di matrice.To construct a closed generic type from C<T>[], call GetElementType to obtain the generic type definition C<T>; call MakeGenericType on the generic type definition to create the constructed type; and finally call the MakeArrayType method on the constructed type to create the array type. Lo stesso vale per i tipi e ref i tipi di puntatore (ByRef in Visual Basic).The same is true of pointer types and ref types (ByRef in Visual Basic).

Per un elenco delle condizioni invariabili relative ai termini usati dal processo di reflection generico, vedere i commenti sulla proprietà IsGenericType.For a list of the invariant conditions for terms used in generic reflection, see the IsGenericType property remarks.

Tipi annidatiNested Types

Se un tipo generico viene definito usando C#, C++o Visual Basic, i relativi tipi annidati sono tutti generici.If a generic type is defined using C#, C++, or Visual Basic, then its nested types are all generic. Questo vale anche se i tipi annidati non hanno parametri di tipo propri, perché in tutti e tre i linguaggi sono inclusi i parametri di tipo dei tipi di inclusione negli elenchi di parametri di tipo dei tipi annidati.This is true even if the nested types have no type parameters of their own, because all three languages include the type parameters of enclosing types in the type parameter lists of nested types. Si considerino le classi seguenti:Consider the following classes:

generic<typename T> public ref class Outermost
{
public:
    generic<typename U> ref class Inner
    {
    public:
        generic<typename V> ref class Innermost1 {};
        ref class Innermost2 {};
    };
};
public class Outermost<T>
{
    public class Inner<U>
    {
        public class Innermost1<V> {}
        public class Innermost2 {}
    }
}
Public Class Outermost(Of T)
    Public Class Inner(Of U)
        Public Class Innermost1(Of V)
        End Class
        Public Class Innermost2
        End Class
    End Class
End Class

L'elenco dei parametri di tipo della classe Inner annidata ha due parametri T di Utipo, e, il primo dei quali è il parametro di tipo della relativa classe che lo contiene.The type parameter list of the nested class Inner has two type parameters, T and U, the first of which is the type parameter of its enclosing class. Analogamente, l'elenco dei parametri di tipo della Innermost1 classe annidata presenta tre Tparametri Udi tipo V,, T e U , con e provenienti dalle classi che li racchiudono.Similarly, the type parameter list of the nested class Innermost1 has three type parameters, T, U, and V, with T and U coming from its enclosing classes. La classe Innermost2 annidata ha due parametri di tipo U, T e, che derivano dalle classi che li racchiudono.The nested class Innermost2 has two type parameters, T and U, which come from its enclosing classes.

Se l'elenco di parametri del tipo di inclusione ha più di un parametro di tipo, tutti i parametri di tipo in ordine vengono inclusi nell'elenco dei parametri di tipo del tipo annidato.If the parameter list of the enclosing type has more than one type parameter, all the type parameters in order are included in the type parameter list of the nested type.

Per costruire un tipo generico dalla definizione di tipo generico per un tipo annidato, chiamare MakeGenericType il metodo con la matrice formata concatenando le matrici degli argomenti di tipo di tutti i tipi di inclusione, a partire dal tipo generico più esterno e terminando con digitare la matrice di argomenti del tipo annidato, se dispone di parametri di tipo propri.To construct a generic type from the generic type definition for a nested type, call the MakeGenericType method with the array formed by concatenating the type argument arrays of all the enclosing types, beginning with the outermost generic type, and ending with the type argument array of the nested type itself, if it has type parameters of its own. Per creare un'istanza di Innermost1, chiamare il MakeGenericType metodo con una matrice contenente tre tipi, da assegnare a T, U e V. Per creare un'istanza di Innermost2, chiamare il MakeGenericType metodo con una matrice contenente due tipi, da assegnare a T e U.To create an instance of Innermost1, call the MakeGenericType method with an array containing three types, to be assigned to T, U, and V. To create an instance of Innermost2, call the MakeGenericType method with an array containing two types, to be assigned to T and U.

Le lingue propagano i parametri di tipo dei tipi di inclusione in questo modo, quindi è possibile usare i parametri di tipo di un tipo di inclusione per definire campi di tipi annidati.The languages propagate the type parameters of enclosing types in this fashion so you can use the type parameters of an enclosing type to define fields of nested types. In caso contrario, i parametri di tipo non rientrano nell'ambito nei corpi dei tipi annidati.Otherwise, the type parameters would not be in scope within the bodies of the nested types. È possibile definire tipi annidati senza propagare i parametri di tipo dei tipi di inclusione, creando codice in assembly dinamici o utilizzando Ilasm. exe (assembler il).It is possible to define nested types without propagating the type parameters of enclosing types, by emitting code in dynamic assemblies or by using the Ilasm.exe (IL Assembler). Si consideri il codice seguente per l'assembler MSIL:Consider the following code for the MSIL assembler:

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

In questo esempio non è possibile definire un campo di tipo T o U nella classe Innermost, perché tali parametri di tipo non sono inclusi nell'ambito.In this example, it is not possible to define a field of type T or U in class Innermost, because those type parameters are not in scope. Il codice assembler seguente definisce le classi annidate che si comportano come se C++fossero definite in, C#Visual Basic e:The following assembler code defines nested classes that behave the way they would if defined in C++, Visual Basic, and C#:

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

È possibile utilizzare Ildasm. exe (DISASSEMBLER il) per esaminare le classi annidate definite nei linguaggi di alto livello e osservare questo schema di denominazione.You can use the Ildasm.exe (IL Disassembler) to examine nested classes defined in the high-level languages and observe this naming scheme.

Si applica a

Vedi anche