Reflexão e tipos genérico

Do ponto de vista da reflexão, a diferença entre um tipo genérico e um tipo comum é que um tipo genérico tem associado a ele um conjunto de parâmetros de tipo (se for uma definição de tipo genérico) ou argumentos de tipo (se ele for um tipo construído). Um método genérico difere de um método comum da mesma maneira.

Existem duas chaves para compreender como reflexão trata tipos e métodos genéricos:

  • Os parâmetros de tipo de definições de tipo genérico e método genérico são representados por instâncias de Type classe.

    Observação

    Muitas propriedades e métodos de Type tem um comportamento diferente quando um Type objeto representa um parâmetro de tipo genérico.Essas diferenças são documentadas nos tópicos da propriedade e método.Por exemplo, consulte IsAutoClass e DeclaringType.Além disso, alguns membros são válido somente quando uma Type objeto representa um parâmetro de tipo genérico.Por exemplo, ver GetGenericTypeDefinition.

  • Se uma instância de Type representa um tipo genérico, e em seguida, ele inclui uma matriz de tipos que representam os parâmetros de tipo (para definições de tipo genérico) ou os argumentos de tipo (para tipos construídos). O mesmo é verdadeiro de uma instância de MethodInfo classe que representa um método genérico.

Reflexo fornece métodos de Type e MethodInfo que permitem que você acessar a matriz de parâmetros de tipo e para determinar se uma instância de Type representa um parâmetro de tipo ou um tipo real.

Por exemplo, o código que demonstra os métodos abordados aqui, consulte Como: Examinar e instanciar tipos genéricos com reflexão.

A seguinte descrição pressupõe familiaridade com a terminologia de genéricos, como, por exemplo, a diferença entre os parâmetros de tipo e os argumentos e os tipos de construído abertos ou fechados. Para obter mais informações, consulte Classes genéricas no .NET Framework.

Esta visão geral consiste nas seções a seguir:

  • Este é um tipo genérico ou método?

  • Gerando fechados tipos genéricos

  • Examinando os argumentos de tipo e os parâmetros de tipo

  • Constantes

  • Tópicos relacionados

Este é um tipo genérico ou método?

Quando você usa reflexão para examinar um tipo desconhecido, representado por uma instância de Type, use o IsGenericType a propriedade para determinar se o tipo desconhecido é genérico. Ele retorna true se o tipo é genérico. Da mesma forma, quando você examinar um método desconhecido, representado por uma instância da MethodInfo da classe, use o IsGenericMethod a propriedade para determinar se o método é genérica.

Este é um tipo genérico ou definição de método?

Use o IsGenericTypeDefinition propriedade para determinar se um Type objeto representa uma definição de tipo genérico e o uso de IsGenericMethodDefinition método para determinar se um MethodInfo representa uma definição de método genérico.

Definições de tipo e um método genéricas são os modelos a partir do qual pode ser instanciados tipos são criados. Tipos de genéricos na.NET Framework, como de biblioteca de classe Dictionary<TKey, TValue>, que são definições de tipo genérico.

É o tipo ou método abertas ou fechadas?

Um tipo genérico ou método está fechado se pode ser instanciados tipos foram substituídos para todos os seus parâmetros de tipo, incluindo todos os parâmetros de tipo de todos os tipos de delimitadoras. Se ela estiver fechada, você só pode criar uma instância de um tipo genérico. O Type.ContainsGenericParameters retorna a propriedade true se um tipo é aberta. Para métodos, o MethodInfo.ContainsGenericParameters método executa a mesma função.

Voltar ao topo

Gerando fechados tipos genéricos

Depois de ter um tipo genérico ou definição de método, use o MakeGenericType método para criar um tipo genérico fechado ou o MakeGenericMethod método para criar um MethodInfo para um método genérico fechado.

Obtendo o tipo genérico ou definição de método

Se você tiver um tipo genérico aberto ou o método não é um tipo genérico ou definição de método, não é possível criar instâncias dele e você não pode fornecer os parâmetros de tipo que estão faltando. Você deve ter uma definição de tipo ou método genérica. Use o GetGenericTypeDefinition método para obter a definição de tipo genérico ou o GetGenericMethodDefinition método para obter a definição de método genérico.

Por exemplo, se você tiver um Type objeto representando Dictionary<int, string> (Dictionary(Of Integer, String) em Visual Basic) e você deseja criar o tipo de Dictionary<string, MyClass>, você pode usar o GetGenericTypeDefinition método para obter um Type representando Dictionary<TKey, TValue> e use o MakeGenericType método para produzir um Type representando Dictionary<int, MyClass>.

Para obter um exemplo de um tipo genérico aberto que não é um tipo genérico, consulte "Parâmetro de tipo ou argumento de tipo" neste tópico.

Voltar ao topo

Examinando os argumentos de tipo e os parâmetros de tipo

Use o Type.GetGenericArguments método para obter uma matriz de Type os objetos que representam os tipos de parâmetros ou argumentos de tipo de um tipo genérico e, em seguida, use o MethodInfo.GetGenericArguments método para fazer o mesmo para um método genérico.

Se você souber que uma Type objeto representa um parâmetro de tipo, há muitas outras perguntas reflexão can resposta. Você pode determinar fonte do parâmetro de tipo, sua posição e suas restrições.

O parâmetro de tipo ou o argumento de tipo

Para determinar se um determinado elemento da matriz é um parâmetro de tipo ou um argumento de tipo, use o IsGenericParameter propriedade. O IsGenericParameter é a propriedade true se o elemento é um parâmetro de tipo.

Um tipo genérico pode ser aberto sem ser uma definição de tipo genérico, caso em que ele tem uma mistura de argumentos de tipo e os parâmetros de tipo. Por exemplo, o código a seguir, class D deriva de um tipo criado, substituindo o primeiro parâmetro de tipo de D para o segundo parâmetro do tipo de B.

class B<T, U> {}
class D<V, W> : B<int, V> {}
Class B(Of T, U)
End Class
Class D(Of V, W)
    Inherits B(Of Integer, V)
End Class
generic<typename T, typename U> ref class B {};
generic<typename V, typename W> ref class D : B<int, V> {};

Se você obtiver um Type objeto representando D<V, W> e use o BaseType propriedade para obter o seu tipo base, resultante type B<int, V> está aberto, mas não é uma definição de tipo genérico.

Origem de um parâmetro genérico

Um parâmetro de tipo genérico pode vir do tipo de que análise, a partir de um tipo de delimitador ou um método genérico. Você pode determinar a origem do parâmetro de tipo genérico da seguinte maneira:

  • Primeiro, use o DeclaringMethod propriedade para determinar se o parâmetro de tipo vem de um método genérico. Se o valor da propriedade não é uma referência nula (Nothing em Visual Basic), e em seguida, a fonte é um método genérico.

  • Se a fonte não é um método genérico, use o DeclaringType propriedade para determinar o tipo genérico do parâmetro de tipo genérico pertence a.

Se o parâmetro de tipo pertencer a um método genérico, o DeclaringType propriedade retorna o tipo declarado o método genérico, o que é irrelevante.

Posição de um parâmetro genérico

Em raras situações, é necessário determinar a posição de um parâmetro de tipo na lista de parâmetros de tipo de sua declaração de classe. Por exemplo, suponha que você tenha um Type objeto que representa o B<int, V> o tipo do exemplo anterior. O GetGenericArguments método lhe oferece uma lista de argumentos de tipo e ao examinar V você pode usar o DeclaringMethod e DeclaringType Propriedades para descobrir de onde ele vem. Você pode usar o GenericParameterPosition propriedade para determinar sua posição na lista de parâmetro de tipo de onde foi definido. Neste exemplo, V é a posição 0 (zero) na lista de parâmetro de tipo de onde foi definido.

O tipo base e restrições de Interface

Use o GetGenericParameterConstraints método para obter a restrição do tipo base e as restrições de interface de um parâmetro de tipo. A ordem dos elementos da matriz não é significativa. Um elemento representa uma restrição de interface, se ele for um tipo de interface.

Atributos de parâmetro genérico

O GenericParameterAttributes propriedade obtém uma GenericParameterAttributes valor que indica a variação (covariância ou/contravariância) e as restrições especiais de um parâmetro de tipo.

Covariância e Contravariance

Para determinar se um parâmetro de tipo é covariant ou contravariant, aplicar o GenericParameterAttributes.VarianceMask de máscara para o GenericParameterAttributes o valor retornado pelo GenericParameterAttributes propriedade. Se o resultado for GenericParameterAttributes.None, o parâmetro de tipo é constante. Consulte Covariância e/contravariância no genéricos.

Restrições especiais

Para determinar as restrições especiais de um parâmetro de tipo, aplicar o GenericParameterAttributes.SpecialConstraintMask de máscara para o GenericParameterAttributes o valor retornado pelo GenericParameterAttributes propriedade. Se o resultado for GenericParameterAttributes.None, há sem restrições especiais. Um parâmetro de tipo pode ser restrita a ser um tipo de referência para ser um tipo de valor não nulo e ter um construtor padrão.

Voltar ao topo

Constantes

Para uma tabela das condições invariável para termos comuns em reflexão para tipos genéricos, consulte Type.IsGenericType. Para termos adicionais relacionadas aos métodos genéricos, consulte MethodInfo.IsGenericMethod.

Voltar ao topo

Tópicos relacionados

Título

Descrição

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

Mostra como usar as propriedades e métodos de Type e MethodInfo para examinar tipos genéricos.

Classes genéricas no .NET Framework

Descreve o recurso genéricos e como ele é suportado na.NET Framework.

Como: Definir um tipo genérico com reflexão emitir

Mostra como usar a reflexão emitir para gerar tipos genéricos em assemblies dinâmicos.

Exibindo informações de tipo

Descreve o Type de classe e fornece exemplos de código que ilustram como usar Type com várias classes de reflexão para obter informações sobre os construtores, métodos, campos, propriedades e eventos.

Voltar ao topo