Información general sobre la reflexión y los genéricos
Actualización: noviembre 2007
Hay dos claves para entender la forma en que la reflexión controla los tipos y métodos genéricos:
Las instancias de la clase Type representan los parámetros de tipo de las definiciones de tipos genéricos y métodos genéricos.
Nota:
Muchas propiedades y métodos de Type presentan un comportamiento distinto cuando un objeto Type representa un parámetro de tipo genérico. Estas diferencias se describen en la documentación relativa a los temas sobre propiedades y métodos. Por ejemplo, vea IsAutoClass y DeclaringType. Además, algunos miembros sólo son válidos cuando un objeto Type representa un parámetro de tipo genérico. Por ejemplo, vea GetGenericTypeDefinition.
Si una instancia de Type representa un tipo genérico, entonces incluye una matriz de tipos que representa los parámetros de tipo (para definiciones de tipos genéricos) o los argumentos de tipo (para tipos construidos). Esto mismo es cierto para una instancia de la clase MethodInfo que representa un método genérico.
La reflexión proporciona métodos de las clases Type y MethodInfo que le permiten obtener acceso a la matriz de parámetros de tipo y le permiten determinar si una instancia de Type representa un parámetro de tipo o un tipo real.
Para obtener un ejemplo de código donde se muestran los métodos que aquí se describen, vea Cómo: Examinar y crear instancias de tipos genéricos mediante la reflexión.
En la siguiente descripción se asume que el lector está familiarizado con la terminología relativa a los genéricos, como la diferencia que existe entre argumentos y parámetros de tipo, y entre tipos construidos abiertos o cerrados. Para obtener más información, vea Información general sobre los genéricos de .NET Framework.
Determinar si se trata de un tipo o método genérico
Cuando utilice la reflexión para examinar un tipo desconocido, representado por una instancia de Type, utilice la propiedad IsGenericType para determinar si el tipo desconocido es genérico. Si el tipo es genérico, devuelve true. Del mismo modo, cuando examine un método desconocido, representado por una instancia de la clase MethodInfo, utilice la propiedad IsGenericMethod para determinar si el método es genérico.
Determinar si se trata de una definición de tipo o método genérico
Utilice la propiedad IsGenericTypeDefinition para determinar si un objeto Type representa una definición de tipo genérico y utilice el método IsGenericMethodDefinition para determinar si un objeto MethodInfo representa una definición de método genérico.
Las definiciones de tipos y métodos genéricos son las plantillas a partir de las que se crean los tipos de los que se pueden crear instancias. Los tipos genéricos de la biblioteca de clases de .NET Framework, como Dictionary<TKey, TValue>, son definiciones de tipos genéricos.
Determinar si el tipo o método está abierto o cerrado
Un tipo o método genérico está cerrado si los tipos a partir de los que pueden crearse instancias se han sustituido para todos sus parámetros de tipo, incluidos todos los parámetros de tipo de todos los tipos envolventes. Sólo se puede crear una instancia de un tipo genérico si está cerrado. La propiedad Type.ContainsGenericParameters devuelve true si un tipo está abierto. En el caso de los métodos, el método MethodInfo.ContainsGenericParameters realiza la misma función.
Generar tipos genéricos cerrados
Una vez que disponga de una definición de tipo o método genérico, utilice el método MakeGenericType para crear un tipo genérico cerrado o el método MakeGenericMethod para crear un objeto MethodInfo para un método genérico cerrado.
Obtener la definición de tipo o método genérico
Si dispone de un tipo o método genérico abierto que no sea una definición de tipo o método genérico, no podrá crear instancias del mismo y no podrá suministrar los parámetros de tipo de falten. Debe disponer de una definición de tipo o método genérico. Utilice el método GetGenericTypeDefinition para obtener la definición de tipo genérico o el método GetGenericMethodDefinition para obtener la definición de método genérico.
Por ejemplo, si dispone de un objeto Type que representa Dictionary<int, string> (Dictionary(Of Integer, String) en Visual Basic) y desea crear el tipo Dictionary<string, MyClass>, puede utilizar el método GetGenericTypeDefinition para obtener un Type que represente Dictionary<TKey, TValue> y, a continuación, utilizar el método MakeGenericType para generar un Type que represente Dictionary<int, MyClass>.
Para obtener un ejemplo de un tipo genérico abierto que no sea un tipo genérico, vea "Parámetro de tipo o argumento de tipo" más adelante en este tema.
Examinar argumentos de tipo y parámetros de tipo
Utilice el método Type.GetGenericArguments para obtener una matriz de objetos Type que represente los parámetros de tipo o argumentos de tipo de un tipo genérico, y utilice el método MethodInfo.GetGenericArguments para hacer lo mismo con un método genérico.
Cuando se sabe que un objeto Type representa un parámetro de tipo, hay muchas cuestiones adicionales a las que puede responder la reflexión; se puede determinar el origen del parámetro de tipo, su posición y sus restricciones.
Parámetro de tipo o argumento de tipo
Para determinar si un elemento determinado de la matriz es un parámetro de tipo o un argumento de tipo, utilice la propiedad IsGenericParameter. La propiedad IsGenericParameter es true si el elemento es un parámetro de tipo.
Un tipo genérico puede estar abierto sin necesidad de ser una definición de tipo genérico, en cuyo caso dispondrá de una mezcla de argumentos de tipo y parámetros de tipo. Por ejemplo, en el siguiente código, la clase D se deriva de un tipo creado mediante la sustitución del primer parámetro de tipo de D por el segundo parámetro de 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> {};
Si obtiene un objeto Type que representa D<V, W> y utiliza la propiedad BaseType para obtener su tipo base, el tipo type B<int, V> resultante estará abierto, pero no será una definición de tipo genérico.
Origen de un parámetro genérico
Un parámetro de tipo genérico podría proceder del tipo que está examinando, de un tipo envolvente o de un método genérico. Puede determinar el origen del parámetro de tipo genérico tal y como se muestra a continuación:
En primer lugar, utilice la propiedad DeclaringMethod para determinar si el parámetro de tipo procede de un método genérico. Si el valor de la propiedad no es una referencia nula (Nothing en Visual Basic), entonces el origen es un método genérico.
Si el origen no es un método genérico, utilice la propiedad DeclaringType para determinar el tipo genérico al que el parámetro de tipo genérico pertenece.
Si el parámetro de tipo pertenece a un método genérico, la propiedad DeclaringType devolverá el tipo que declaró el método genérico, lo que resulta irrelevante.
Posición de un parámetro genérico
En situaciones excepcionales, es necesario determinar la posición de un parámetro de tipo en la lista de parámetros de tipo de su clase declarante. Por ejemplo, supongamos que dispone de un objeto Type que representa el tipo B<int, V> del ejemplo anterior. El método GetGenericArguments proporciona una lista de argumentos de tipo y cuando se examina V se pueden utilizar las propiedades DeclaringMethod y DeclaringType para descubrir su procedencia. A continuación, se puede utilizar la propiedad GenericParameterPosition para determinar su posición en la lista de parámetros de tipo donde se definió. En este ejemplo, V está en posición 0 (cero) en la lista de parámetros de tipo donde se definió.
Tipo base y restricciones de interfaz
Utilice el método GetGenericParameterConstraints para obtener la restricción de tipo base y las restricciones de interfaz de un parámetro de tipo. El orden de los elementos de la matriz no es significativo. Un elemento representa una restricción de interfaz si se trata de un tipo de interfaz.
Restricciones especiales
La propiedad GenericParameterAttributes obtiene un valor GenericParameterAttributes que indica las restricciones especiales. Un parámetro de tipo puede restringirse para ser un tipo de referencia, un tipo de valor que no acepte valores NULL y para disponer de un constructor predeterminado.
Invariables
Para obtener una tabla de las condiciones invariables para términos comunes en la reflexión de tipos genéricos, vea Type.IsGenericType. Para obtener términos adicionales relativos a los métodos genéricos, vea MethodInfo.IsGenericMethod.
Vea también
Tareas
Cómo: Examinar y crear instancias de tipos genéricos mediante la reflexión
Conceptos
Información general sobre los genéricos de .NET Framework