Información general sobre descriptores de tipos

La arquitectura TypeDescriptor mejora las funciones de reflexión de .NET.

Arquitectura de descriptores de tipos

La arquitectura TypeDescriptor está basada en el motor de reflexión básico y agrega reglas y características adicionales. Por ejemplo, la clase TypeDescriptor admite la combinación de propiedades Extender de un objeto IContainer y también admite propiedades de filtrado y eventos a través de un objeto IDesigner.

Además, la arquitectura TypeDescriptor habilita varias funciones. En la tabla siguiente se muestran las funciones de la arquitectura.

Función

Descripción

Sustitución de instancias

Permite crear un tipo arbitrario cuando se solicita otro tipo.

Sustitución de metadatos

Permite modificar los metadatos de un objeto.

Redirección de atributos

Permite especificar atributos dinámicamente.

Sustitución y sombreado de destinos

Permite a un objeto sustituir a otro.

Compatibilidad con descriptores de tipos extendidos

Permite el acceso a propiedades de objetos agregadas por otros objetos.

Para posibilitar estas funciones, la clase TypeDescriptor se integra estrechamente con las distintas características del modelo de componentes de .NET Framework. Es compatible con objetos COM, proveedores extensores, diseñadores y propiedades CLR.

Nota

Puede utilizar la arquitectura TypeDescriptor tanto en el código en tiempo de ejecución como en el código en tiempo de diseño.

Para posibilitar la extensibilidad, la clase TypeDescriptor tiene una clase complementaria denominada TypeDescriptionProvider y un atributo complementario denominado TypeDescriptionProviderAttribute. Puede utilizar un objeto TypeDescriptionProviderAttribute en una clase para introducir una manera completamente diferente de exponer metadatos que responda a sus objetivos de diseño.

Clase TypeDescriptionProvider

La clase TypeDescriptionProvider se puede considerar como un complemento para la clase TypeDescriptor. Para una instancia determinada de TypeDescriptor, puede haber varias clases de proveedores de descripciones de tipo, todas las cuales ofrecerían metadatos al objeto TypeDescriptor.

Atributo TypeDescriptionProvider

TypeDescriptionProviderAttribute es un atributo que se puede colocar en una clase. Este atributo se utiliza para indicar que el tipo tiene asociado un proveedor de descripciones de tipo. A su vez, el atributo proporciona, a través de metadatos, un medio de instalar un proveedor de descripciones de tipo. Cuando se pasa este tipo a una API en la clase, TypeDescriptor, TypeDescriptor detecta este atributo, crea una instancia del proveedor de descripciones de tipo descrito dentro de éste y enlaza el proveedor en la tablas internas de TypeDescriptor. Después estas operaciones, TypeDescriptor continúa el procesamiento de la API. El procesamiento permite a un tipo instalar automáticamente a petición un proveedor personalizado de descripciones de tipo.

Funciones del descriptor de tipos

La arquitectura TypeDescriptor permite más funciones de las que proporciona la reflexión de .NET Framework.

Sustitución de instancias

La sustitución de instancias se produce cuando desea crear un tipo, pero el tipo que realmente se crea es diferente del solicitado. La sustitución de la instancia se lleva a cabo si reemplaza todas las llamadas a new con llamadas al método CreateInstance. Este método busca en las tablas internas de TypeDescriptor un objeto TypeDescriptionProvider que esté asociado al tipo de datos dado. Si lo encuentra, delega la llamada a ese objeto.

Sustitución de metadatos

La sustitución de metadatos se produce cuando se modifican los metadatos disponibles para uno o más objetos. Una aplicación común de sustitución de metadatos se da en la implementación de diseñadores. La sustitución de metadatos puede realizarse con proveedores de descripciones de tipo, que es posible agregar y quitar mediante los siguientes métodos en TypeDescriptor:

Redirección de atributos

Hay un número reducido de casos en el modelo de objetos de .NET Framework en los que el tipo de una propiedad se establece expresamente en no específico. Por ejemplo, la propiedad DataSource en la clase DataGridView se identifica como object. Este diseño permite que el origen de datos acepte varios tipos de entrada, pero no proporciona ningún lugar común para agregar metadatos que describan las características de la propiedad. Cada una de las propiedades de origen de datos de .NET Framework necesita tener los mismos metadatos para los convertidores de tipos y los editores de tipos de la interfaz de usuario.

La clase AttributeProviderAttribute soluciona esta situación. Cuando este atributo se coloca en una propiedad, las reglas cambian para obtener los atributos de la colección Attributes del descriptor de propiedad. Normalmente, el descriptor de propiedad recopila los atributos locales y los combina con atributos del tipo de propiedad. Cuando se aplica el atributo AttributeProviderAttribute, los atributos se toman del tipo devuelto de AttributeProviderAttribute, no del tipo de propiedad real. AttributeProviderAttribute se utiliza en los orígenes de datos para apuntar el tipo específico del origen de datos a IListSource, y se colocan los metadatos correspondientes en IListSource para permitir el enlace de datos. Esta redirección permite a partes externas como Visual Studio agregar con facilidad metadatos a todos los orígenes de datos.

Los atributos obtenidos de un tipo declarado en AttributeProviderAttribute presentan una prioridad entre los atributos del tipo de la propiedad y los atributos de la propiedad. El conjunto completo de atributos disponible es la combinación, en orden de prioridad, como se muestra en la lista siguiente:

  1. Atributos de propiedad

  2. Atributos de proveedor de atributos

  3. Atributos de tipo de propiedad

Sustitución y sombreado de destinos

La sustitución de un destino se produce cuando un objeto representa a otro. Una aplicación común de sustitución de destinos se da en la implementación de diseñadores.

En la arquitectura del diseñador de .NET Framework, un componente puede tener asociado un diseñador. Este diseñador puede implementar IDesignerFilter y proporcionar sus propias propiedades. Estas propiedades se combinan con el conjunto de propiedades para el componente al que se asocia el diseñador. Estas propiedades pueden ser nuevas para el componente. También pueden tener el mismo nombre y tipo que las propiedades ya definidas en el componente. Cuando la nueva propiedad tiene el mismo nombre y tipo que una propiedad existente, se denomina sombreado, porque el diseñador oculta, o "sombrea", la propiedad existente en el componente. En la ilustración siguiente se muestra el sombreado de una propiedad.

Sombrear la propiedad Text

Aquí, el componente ofrece dos propiedades, igual que el diseñador. La propiedad Text se ofrece tanto en el diseñador como el componente y es sombreada. El resultado final de una llamada a GetProperties es de tres propiedades. Una en el componente y las otras dos en el diseñador.

Este filtrado de propiedades se lleva a cabo mediante el uso de ITypeDescriptorFilterService, que implementa la superficie de diseño. Se necesitan funciones de TypeDescriptor cuando llega el momento de establecer un valor en la propiedad. El código para establecer un valor en la propiedad Grid se parecería al siguiente:

    gridProp.SetValue(component, value);

La información de tipo real sobre la propiedad apunta a una instancia del diseñador, no del componente. Si se realizara una llamada de reflexión para establecer realmente la propiedad, provocaría una excepción de invocación de destino, ya que la instancia del componente no coincide con el tipo de diseñador.

La clase TypeDescriptor tiene lógica inherente para evitar esta situación. Cuando se realiza una llamada de propiedad, la clase TypeDescriptor comprueba si el tipo de miembro es una instancia del objeto pasado. En ese caso, permite que continúe la llamada. De lo contrario, la clase intenta localizar al diseñador para el objeto, y si lo encuentra y es del tipo correcto, reemplaza la instancia del componente con la instancia del diseñador.

Los métodos siguientes en TypeDescriptor admiten la substitución de destinos:

Compatibilidad con descriptores de tipos extendidos

El método GetExtendedTypeDescriptor devuelve un descriptor de tipos personalizado extendido para el objeto determinado. Un descriptor de tipos extendido es un descriptor de tipos personalizado que ofrece propiedades agregadas a un objeto por otros objetos, pero no definidas en dicho objeto. Por ejemplo, en el modelo de componentes de .NET Framework, los objetos que implementan la interfaz IExtenderProvider pueden asociar propiedades a otros objetos que se encuentran en el mismo objeto IContainer. El método GetTypeDescriptor no devuelve un descriptor de tipos que proporcione estas propiedades extendidas adicionales, pero GetExtendedTypeDescriptor devuelve el conjunto de estas propiedades extendidas. La clase TypeDescriptor combina automáticamente los resultados de estas dos colecciones de propiedades.

Nota

Aunque el modelo de componentes de .NET Framework sólo admite propiedades extendidas, GetExtendedTypeDescriptor se puede utilizar también para eventos y atributos extendidos, si el proveedor de descripciones de tipo lo admite.

Vea también

Referencia

TypeDescriptor

TypeDescriptionProvider

TypeDescriptionProviderAttribute

ICustomTypeDescriptor

CustomTypeDescriptor

IContainer

IDesigner

Otros recursos

Ampliar compatibilidad en tiempo de diseño