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

Definição

Substitui os elementos de uma matriz de tipos pelos parâmetros de tipo da definição de tipo genérico atual e retorna um objeto Type que representa o tipo construído resultante.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

Parâmetros

typeArguments
Type[]

Uma matriz de tipos a serem substituídos pelos parâmetros de tipo do tipo genérico atual.An array of types to be substituted for the type parameters of the current generic type.

Retornos

Um Type representando o tipo construído formado substituindo os elementos do typeArguments pelos parâmetros de tipo do tipo genérico atual.A Type representing the constructed type formed by substituting the elements of typeArguments for the type parameters of the current generic type.

Exceções

O tipo atual não representa uma definição de tipo genérica.The current type does not represent a generic type definition. Ou seja, IsGenericTypeDefinition retorna false.That is, IsGenericTypeDefinition returns false.

typeArguments é null.typeArguments is null.

- ou --or- Qualquer elemento de typeArguments é null.Any element of typeArguments is null.

O número de elementos em typeArguments não é igual ao número de parâmetros de tipo na definição de tipo genérico atual.The number of elements in typeArguments is not the same as the number of type parameters in the current generic type definition.

- ou --or- Nenhum elemento do typeArguments satisfaz as restrições especificadas para o parâmetro de tipo correspondente do tipo genérico atual.Any element of typeArguments does not satisfy the constraints specified for the corresponding type parameter of the current generic type.

- ou --or- typeArguments contém um elemento que é um tipo de ponteiro (IsPointer retorna true), um tipo by-ref (IsByRef retorna true) ou Void.typeArguments contains an element that is a pointer type (IsPointer returns true), a by-ref type (IsByRef returns true), or Void.

O método chamado não é suportado na classe base.The invoked method is not supported in the base class. As classes derivadas devem fornecer uma implementação.Derived classes must provide an implementation.

Exemplos

O exemplo a seguir usa MakeGenericType o método para criar um tipo construído a partir da definição de tipo Dictionary<TKey,TValue> genérico para o tipo.The following example uses the MakeGenericType method to create a constructed type from the generic type definition for the Dictionary<TKey,TValue> type. O tipo construído representa um Dictionary<TKey,TValue> dos Test objetos com chaves de cadeia de caracteres.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

Comentários

O MakeGenericType método permite que você escreva o código que atribui tipos específicos aos parâmetros de tipo de uma definição de tipo genérico, criando assim um Type objeto que representa um tipo construído específico.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. Você pode usar esse Type objeto para criar instâncias de tempo de execução do tipo construído.You can use this Type object to create run-time instances of the constructed type.

Tipos construídos com MakeGenericType podem ser abertos, ou seja, alguns dos seus argumentos de tipo podem ser parâmetros de tipo de métodos genéricos delimitadores ou tipos.Types constructed with MakeGenericType can be open, that is, some of their type arguments can be type parameters of enclosing generic methods or types. Você pode usar esses tipos construídos abertos ao emitir assemblies dinâmicos.You might use such open constructed types when you emit dynamic assemblies. Por exemplo, considere as classes Base e Derived no código a seguir.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

Para gerar Derived em um assembly dinâmico, é necessário construir seu tipo base.To generate Derived in a dynamic assembly, it is necessary to construct its base type. Para fazer isso, chame o MakeGenericType método em um Type objeto que representa a Baseclasse, usando os argumentos Int32 de tipo genérico e o V parâmetro Derivedde tipo de.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. Como tipos e parâmetros de tipo genérico são representados Type por objetos, uma matriz que contém ambos pode ser passada MakeGenericType para o método.Because types and generic type parameters are both represented by Type objects, an array containing both can be passed to the MakeGenericType method.

Observação

Um tipo construído, como Base<int, V> é útil ao emitir código, mas você não pode chamar o MakeGenericType método nesse tipo porque ele não é uma definição de tipo genérico.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. Para criar um tipo construído fechado que pode ser instanciado, primeiro chame o GetGenericTypeDefinition método para obter um Type objeto que representa a definição de tipo genérico e MakeGenericType , em seguida, chame com os argumentos de tipo desejados.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.

O Type objeto retornado por MakeGenericType é o mesmo que o Type obtido chamando o GetType método do tipo construído resultante ou o GetType método de qualquer tipo construído que foi criado com base no mesmo genérico definição de tipo usando os mesmos argumentos de 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.

Observação

Uma matriz de tipos genéricos não é, em si, um tipo genérico.An array of generic types is not itself a generic type. Você não pode MakeGenericType chamar em um tipo de matriz C<T>[] ,Dim ac() As C(Of T) como (em Visual Basic).You cannot call MakeGenericType on an array type such as C<T>[] (Dim ac() As C(Of T) in Visual Basic). Para construir um tipo genérico fechado a C<T>[]partir de GetElementType , chame para obter a definição C<T>de tipo MakeGenericType genérico; chame na definição de tipo genérico para criar o tipo construído; e MakeArrayType finalmente chame o método em o tipo construído para criar o tipo de matriz.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. O mesmo é verdadeiro para tipos de ponteiro ref e tiposByRef (em Visual Basic).The same is true of pointer types and ref types (ByRef in Visual Basic).

Para obter uma lista das condições invariáveis para termos usados na reflexão genérica, consulte os comentários da propriedade IsGenericType.For a list of the invariant conditions for terms used in generic reflection, see the IsGenericType property remarks.

Tipos aninhadosNested Types

Se um tipo genérico for definido usando C#, C++ou Visual Basic, seus tipos aninhados serão todos genéricos.If a generic type is defined using C#, C++, or Visual Basic, then its nested types are all generic. Isso é verdadeiro mesmo que os tipos aninhados não tenham nenhum parâmetro de tipo próprio, porque todos os três idiomas incluem os parâmetros de tipo dos tipos delimitadores nas listas de parâmetros de tipo de tipos aninhados.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. Considere as seguintes classes: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

A lista de parâmetros de tipo da classe Inner aninhada tem dois parâmetros T de Utipo, e o primeiro é o parâmetro de tipo de sua classe de delimitadora.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. Da mesma forma, a lista de parâmetros de tipo Innermost1 da classe aninhada tem três Uparâmetros de Vtipo, T T, U e, com e provenientes de suas classes de circunscrição.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. A classe Innermost2 aninhada tem dois T parâmetros de tipo Ue, que são provenientes de suas classes de circunscrição.The nested class Innermost2 has two type parameters, T and U, which come from its enclosing classes.

Se a lista de parâmetros do tipo delimitador tiver mais de um parâmetro de tipo, todos os parâmetros de tipo na ordem serão incluídos na lista de parâmetros de tipo do tipo aninhado.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.

Para construir um tipo genérico a partir da definição de tipo genérico para um tipo aninhado MakeGenericType , chame o método com a matriz formada concatenando as matrizes de argumento de tipo de todos os tipos delimitadores, começando com o tipo genérico mais externo e terminando com o matriz de argumento de tipo do próprio tipo aninhado, se ele tiver parâmetros de tipo próprios.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. Para criar uma instância do Innermost1, chame o MakeGenericType método com uma matriz que contém três tipos, a ser atribuído a T, U e V. Para criar uma instância do Innermost2, chame o MakeGenericType método com uma matriz que contém dois tipos, a ser atribuído 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.

As linguagens propagam os parâmetros de tipo dos tipos de circunscrição dessa maneira para que você possa usar os parâmetros de tipo de um tipo delimitador para definir campos de tipos aninhados.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. Caso contrário, os parâmetros de tipo não estarão no escopo dentro dos corpos dos tipos aninhados.Otherwise, the type parameters would not be in scope within the bodies of the nested types. É possível definir tipos aninhados sem propagar os parâmetros de tipo dos tipos delimitadores, emitindo código em assemblies dinâmicos ou usando o 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). Considere o seguinte código para o Assembler MSIL:Consider the following code for the MSIL assembler:

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

Neste exemplo, não é possível definir um campo do tipo T ou U na classe Innermost, porque esses parâmetros de tipo não estão no escopo.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. O código do assembler a seguir define classes aninhadas que se comportam C++da maneira como seriam C#definidas em, 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> {  
        }  
    }  
}  

Você pode usar o ILDASM. exe (desmontador de Il) para examinar classes aninhadas definidas nas linguagens de alto nível e observar esse esquema de nomenclatura.You can use the Ildasm.exe (IL Disassembler) to examine nested classes defined in the high-level languages and observe this naming scheme.

Aplica-se a

Veja também