Exportar (0) Imprimir
Expandir Tudo
Este artigo foi traduzido por máquina. Coloque o ponteiro do mouse sobre as frases do artigo para ver o texto original. Mais informações.
Tradução
Original
Este tópico ainda não foi avaliado como - Avalie este tópico

Como: Examinar e Instantiate tipos genéricos com reflexão

Informações sobre tipos genéricos são obtidas da mesma maneira como informações sobre outros tipos: examinando um objeto Type que representa o tipo genérico.A diferença princípio é que um tipo genérico possui uma lista de objetos Type que representam seus parâmetros de tipo genérico.O primeiro procedimento nesta seção examina tipos genéricos.

Você pode criar um objeto Type que representa um tipo construído pelos argumentos Tipo de vinculação aos parâmetros de tipo de uma definição de tipo genérico.O segundo procedimento demonstra isso.

Para examinar um tipo genérico e seus parâmetros de tipo

  1. Obter uma instância de Type que representa o tipo genérico.No código a seguir, o tipo é obtido usando o operador typeof C# (GetType no Visual Basic, typeid no Visual C++).See the tópico de classe Type for Outro ways to get a objeto Type.Anotação that in the rest of this procedimento, the tipo is contained in a nomeado parâmetro método t.

    Type d1 = typeof(Dictionary<,>);
    
    
    
  2. Use a propriedade IsGenericType para determinar se o tipo é genérico e use a propriedade IsGenericTypeDefinition para determinar se o tipo é uma definição de tipo genérico.

    Console.WriteLine("   Is this a generic type? {0}",
        t.IsGenericType);
    Console.WriteLine("   Is this a generic type definition? {0}",
        t.IsGenericTypeDefinition);
    
    
    
  3. Obtenha uma matriz que contém os argumentos de tipo genérico, usando o método GetGenericArguments.

    Type[] typeParameters = t.GetGenericArguments();
    
    
    
  4. Para cada argumento Tipo, determine se ele é um parâmetro de tipo (por exemplo, em uma definição de tipo genérico) ou um tipo que foi especificado para um parâmetro de tipo (por exemplo, em um tipo construído), usando a propriedade IsGenericParameter.

    Console.WriteLine("   List {0} type arguments:", 
        typeParameters.Length);
    foreach( Type tParam in typeParameters )
    {
        if (tParam.IsGenericParameter)
        {
            DisplayGenericParameter(tParam);
        }
        else
        {
            Console.WriteLine("      Type argument: {0}",
                tParam);
        }
    }
    
    
    
  5. No sistema do tipo, um parâmetro de tipo genérico é representado por uma instância de Type, exatamente como são tipos comuns.O código a seguir exibe a posição de parâmetro e nome de um objeto Type que representa um parâmetro de tipo genérico.A posição de parâmetro é trivial informações aqui; é mais interessantes quando você está examinando um parâmetro de tipo que foi usado como um argumento Tipo de outro tipo genérico.

    private static void DisplayGenericParameter(Type tp)
    {
        Console.WriteLine("      Type parameter: {0} position {1}", 
            tp.Name, tp.GenericParameterPosition);
    
    
    
  6. Determine the restrição tipo base and the Constraints interface of a parâmetro de tipo genérico by Using the método GetGenericParameterConstraints to Obtain Tudo the Constraints in a single matriz.As restrições não são garantidas estar em qualquer ordem determinada.

    Type classConstraint = null;
    
    foreach(Type iConstraint in tp.GetGenericParameterConstraints())
    {
        if (iConstraint.IsInterface)
        {
            Console.WriteLine("         Interface constraint: {0}",
                iConstraint);
        }
    }
    
    if (classConstraint != null)
    {
        Console.WriteLine("         Base type constraint: {0}", 
            tp.BaseType);
    }
    else
        Console.WriteLine("         Base type constraint: None"); 
    
    
    
  7. Use the propriedade GenericParameterAttributes to Descobrir the special Constraints on a parâmetro tipo, such as requiring that it be a tipo de referência.A propriedade também inclui os valores que representam a variância, que você pode mascarar desativar conforme mostrado no código a seguir.

    GenericParameterAttributes sConstraints = 
        tp.GenericParameterAttributes & 
        GenericParameterAttributes.SpecialConstraintMask;
    
    
    
  8. The Attributes restrição Special are Sinalizars, and the same Sinalizar (GenericParameterAttributes.None) that represents no Constraints Special also não represents covariância or contravariância.Assim, você deve usar a máscara apropriada para testar qualquer uma dessas condições.In this maiúsculas e minúsculas, use GenericParameterAttributes.SpecialConstraintMask to isolate the Especial Flags restrição.

    if (sConstraints == GenericParameterAttributes.None)
    {
        Console.WriteLine("         No special constraints.");
    }
    else
    {
        if (GenericParameterAttributes.None != (sConstraints &
            GenericParameterAttributes.DefaultConstructorConstraint))
        {
            Console.WriteLine("         Must have a parameterless constructor.");
        }
        if (GenericParameterAttributes.None != (sConstraints &
            GenericParameterAttributes.ReferenceTypeConstraint))
        {
            Console.WriteLine("         Must be a reference type.");
        }
        if (GenericParameterAttributes.None != (sConstraints &
            GenericParameterAttributes.NotNullableValueTypeConstraint))
        {
            Console.WriteLine("         Must be a non-nullable value type.");
        }
    }
    
    
    

Um tipo genérico é como um modelo.Não é possível criar instâncias dele, a menos que você especifique os tipos reais para seus parâmetros de tipo genérico.Para fazer isso em tempo de execução, usar reflexo, requer o método MakeGenericType.

Para construir uma instância de um tipo genérico

  1. Obter um objeto Type que representa o tipo genérico.O código a seguir obtém o tipo genérico Dictionary<TKey, TValue> de duas maneiras diferentes: By Using the sobrecarga método Type.GetType(String) with a Cadeia de Caracteres describing the tipo, and by chamado The método GetGenericTypeDefinition on the tipo construído Dictionary<String, Example> (Dictionary(Of String, Example) in Visual Basic).O método MakeGenericType requer uma definição de tipo genérico.

    // Use the typeof operator to create the generic type 
    // definition directly. To specify the generic type definition,
    // omit the type arguments but retain the comma that separates
    // them.
    Type d1 = typeof(Dictionary<,>);
    
    // You can also obtain the generic type definition from a
    // constructed class. In this case, the constructed class
    // is a dictionary of Example objects, with String keys.
    Dictionary<string, Example> d2 = new Dictionary<string, Example>();
    // Get a Type object that represents the constructed type,
    // and from that get the generic type definition. The 
    // variables d1 and d4 contain the same type.
    Type d3 = d2.GetType();
    Type d4 = d3.GetGenericTypeDefinition();
    
    
    
  2. Construir uma matriz de argumentos de tipo para substituir os parâmetros de tipo.A matriz deve conter o número correto de Type Objetos, na mesma ordem em que aparecem na lista parâmetro de tipo.Neste maiúsculas e minúsculas, a chave (Primeiro parâmetro do tipo) é do tipo String, e os valores de dicionário são instâncias de uma classe nomeado Example.

    Type[] typeArgs = {typeof(string), typeof(Example)};
    
    
    
  3. Call the método MakeGenericType to BIND the Arguments tipo to the tipo Parâmetros and the tipo construção.

    Type constructed = d1.MakeGenericType(typeArgs);
    
    
    
  4. Use a sobrecarga método CreateInstance(Type) para criar um objeto do tipo construído.O código a seguir armazena duas instâncias da classe Example no objeto Dictionary<String, Example> resultante.

    object o = Activator.CreateInstance(constructed);
    
    
    

O exemplo de código a seguir define um método DisplayGenericType para examinar as definições de tipo genérico e construídos tipos usados no código e exibir suas informações.O método DisplayGenericType mostra como usar o IsGenericType, IsGenericParameter, GenericParameterPosition propriedades e o método GetGenericArguments.

O exemplo também define um método DisplayGenericParameter para examinar um parâmetro de tipo genérico e exibir suas restrições.

O exemplo de código define um conjunto de tipos de teste, incluindo um tipo genérico que ilustra restrições de parâmetro de tipo e mostra como exibir informações sobre esses tipos.

O exemplo constrói um tipo da classe Dictionary<TKey, TValue> criando uma matriz de argumentos de tipo e chamar o método MakeGenericType.O programa compara o objeto Type construído usando MakeGenericType com um objeto Type obtido usando typeof (GetType no Visual Basic), demonstrando que eles sejam os mesmos.Da mesma forma, o programa usa o método GetGenericTypeDefinition para obter a definição de tipo genérico do tipo construído e compara-lo para o objeto que representa a classe TypeDictionary<TKey, TValue>.

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Security.Permissions;

// Define an example interface.
public interface ITestArgument {}

// Define an example base class.
public class TestBase {}

// Define a generic class with one parameter. The parameter
// has three constraints: It must inherit TestBase, it must
// implement ITestArgument, and it must have a parameterless
// constructor.
public class Test<T> where T : TestBase, ITestArgument, new() {}

// Define a class that meets the constraints on the type
// parameter of class Test.
public class TestArgument : TestBase, ITestArgument
{
    public TestArgument() {}
}

public class Example
{
    // The following method displays information about a generic
    // type.
    private static void DisplayGenericType(Type t)
    {
        Console.WriteLine("\r\n {0}", t);
        Console.WriteLine("   Is this a generic type? {0}",
            t.IsGenericType);
        Console.WriteLine("   Is this a generic type definition? {0}",
            t.IsGenericTypeDefinition);

        // Get the generic type parameters or type arguments.
        Type[] typeParameters = t.GetGenericArguments();

        Console.WriteLine("   List {0} type arguments:", 
            typeParameters.Length);
        foreach( Type tParam in typeParameters )
        {
            if (tParam.IsGenericParameter)
            {
                DisplayGenericParameter(tParam);
            }
            else
            {
                Console.WriteLine("      Type argument: {0}",
                    tParam);
            }
        }
    }

    // The following method displays information about a generic
    // type parameter. Generic type parameters are represented by
    // instances of System.Type, just like ordinary types.
    private static void DisplayGenericParameter(Type tp)
    {
        Console.WriteLine("      Type parameter: {0} position {1}", 
            tp.Name, tp.GenericParameterPosition);

        Type classConstraint = null;

        foreach(Type iConstraint in tp.GetGenericParameterConstraints())
        {
            if (iConstraint.IsInterface)
            {
                Console.WriteLine("         Interface constraint: {0}",
                    iConstraint);
            }
        }

        if (classConstraint != null)
        {
            Console.WriteLine("         Base type constraint: {0}", 
                tp.BaseType);
        }
        else
            Console.WriteLine("         Base type constraint: None"); 

        GenericParameterAttributes sConstraints = 
            tp.GenericParameterAttributes & 
            GenericParameterAttributes.SpecialConstraintMask;

        if (sConstraints == GenericParameterAttributes.None)
        {
            Console.WriteLine("         No special constraints.");
        }
        else
        {
            if (GenericParameterAttributes.None != (sConstraints &
                GenericParameterAttributes.DefaultConstructorConstraint))
            {
                Console.WriteLine("         Must have a parameterless constructor.");
            }
            if (GenericParameterAttributes.None != (sConstraints &
                GenericParameterAttributes.ReferenceTypeConstraint))
            {
                Console.WriteLine("         Must be a reference type.");
            }
            if (GenericParameterAttributes.None != (sConstraints &
                GenericParameterAttributes.NotNullableValueTypeConstraint))
            {
                Console.WriteLine("         Must be a non-nullable value type.");
            }
        }
    }

    [PermissionSetAttribute(SecurityAction.Demand, Name="FullTrust")]
    public static void Main()
    {
        // Two ways to get a Type object that represents the generic
        // type definition of the Dictionary class. 
        //
        // Use the typeof operator to create the generic type 
        // definition directly. To specify the generic type definition,
        // omit the type arguments but retain the comma that separates
        // them.
        Type d1 = typeof(Dictionary<,>);

        // You can also obtain the generic type definition from a
        // constructed class. In this case, the constructed class
        // is a dictionary of Example objects, with String keys.
        Dictionary<string, Example> d2 = new Dictionary<string, Example>();
        // Get a Type object that represents the constructed type,
        // and from that get the generic type definition. The 
        // variables d1 and d4 contain the same type.
        Type d3 = d2.GetType();
        Type d4 = d3.GetGenericTypeDefinition();

        // Display information for the generic type definition, and
        // for the constructed type Dictionary<String, Example>.
        DisplayGenericType(d1);
        DisplayGenericType(d2.GetType());

        // Construct an array of type arguments to substitute for 
        // the type parameters of the generic Dictionary class.
        // The array must contain the correct number of types, in 
        // the same order that they appear in the type parameter 
        // list of Dictionary. The key (first type parameter)
        // is of type string, and the type to be contained in the
        // dictionary is Example.
        Type[] typeArgs = {typeof(string), typeof(Example)};

        // Construct the type Dictionary<String, Example>.
        Type constructed = d1.MakeGenericType(typeArgs);

        DisplayGenericType(constructed);

        object o = Activator.CreateInstance(constructed);

        Console.WriteLine("\r\nCompare types obtained by different methods:");
        Console.WriteLine("   Are the constructed types equal? {0}",
            (d2.GetType()==constructed));
        Console.WriteLine("   Are the generic definitions equal? {0}",
            (d1==constructed.GetGenericTypeDefinition()));

        // Demonstrate the DisplayGenericType and 
        // DisplayGenericParameter methods with the Test class 
        // defined above. This shows base, interface, and special
        // constraints.
        DisplayGenericType(typeof(Test<>));
    }
}


  • O código contém as instruções using C# (Imports no Visual Basic) necessárias para compilação.

  • Há referências do conjunto de módulos (assembly) adicionais são necessárias.

  • Compilar o Código na linha de comando usando Csc.exe, vbc.exe ou CL.exe.A compilação de Código em Visual Studio, local-lo em um modelo projeto de aplicativo console.

Isso foi útil para você?
(1500 caracteres restantes)
Agradecemos os seus comentários

Contribuições da comunidade

ADICIONAR
A Microsoft está realizando uma pesquisa online para saber sua opinião sobre o site do MSDN. Se você optar por participar, a pesquisa online lhe será apresentada quando você sair do site do MSDN.

Deseja participar?
Mostrar:
© 2014 Microsoft. Todos os direitos reservados.