En la Infraestructura de Lenguaje Común (CLI), los metadatos se refieren a ciertas estructuras de datos integradas en el código del Lenguaje Intermedio Común (CIL) que describen la estructura de alto nivel del código. Los metadatos describen todas las clases y miembros de clase definidos en el ensamblado, así como las clases y miembros de clase que el ensamblado actual llamará desde otro ensamblado. Los metadatos de un método contienen la descripción completa del método, incluyendo la clase (y el ensamblado que contiene la clase), el tipo de retorno y todos los parámetros del método .
Un compilador de lenguaje CLI generará los metadatos y los almacenará en el ensamblado que contiene el CIL . Cuando el entorno de ejecución ejecuta el CIL, verifica que los metadatos del método llamado coincidan con los metadatos almacenados en el método que lo llama. Esto garantiza que un método solo pueda ser llamado con la cantidad exacta de parámetros y los tipos de parámetros correctos.
La plataforma de aplicaciones Windows Runtime , presente en Windows 8 y Windows Phone 8 , utiliza el formato de metadatos CLI para describir las interfaces de los componentes del código escrito en cualquiera de los lenguajes de programación compatibles . Una diferencia en su uso dentro de Common Language Runtime es que un ensamblado normalmente no contiene instrucciones CIL. [ 1 ]
Atributos
Los desarrolladores pueden agregar metadatos a su código mediante atributos . Existen dos tipos de atributos: personalizados y pseudo-personalizados, y para el desarrollador, ambos tienen la misma sintaxis . Los atributos en el código son mensajes que se envían al compilador para generar metadatos. En CIL, los metadatos como los modificadores de herencia, los modificadores de ámbito y prácticamente cualquier elemento que no sean códigos de operación ni flujos, también se denominan atributos.
Un atributo personalizado es una clase regular que hereda de la System.Attributeclase. Un atributo personalizado se puede usar en cualquier método, propiedad, clase o ensamblado completo con la siguiente sintaxis: como en:[AttributeName(optional parameter, optional name=value pairs)]
[Personalizado] [Personalizado(1)] [Personalizado(1, Comentario="sí")]La CLI utiliza ampliamente los atributos personalizados. Windows Communication Framework los usa para definir contratos de servicio, ASP.NET los usa para exponer métodos como servicios web , LINQ to SQL los usa para definir la asignación de clases al esquema relacional subyacente , Visual Studio los usa para agrupar propiedades de un objeto, y el desarrollador de la clase indica la categoría de la clase del objeto aplicando el [Category]atributo personalizado. Los atributos personalizados son interpretados por el código de la aplicación y no por el CLR. Cuando el compilador ve un atributo personalizado, genera metadatos personalizados que el CLR no reconoce. El desarrollador debe proporcionar código para leer los metadatos y actuar en consecuencia. Por ejemplo, el atributo que se muestra en el ejemplo puede ser manejado por el siguiente código:
usando el sistema ;clase CustomAttribute : Attribute { private int paramNumber = 0 ; private string comment = "" ;public CustomAttribute ( int num = 0 ) { paramNumber = num ; }public String Comment { set { comment = value ; } } }El nombre de la clase se asigna al nombre del atributo. El compilador de Visual C# agrega automáticamente la cadena " Attribute" al final de cualquier nombre de atributo. En consecuencia, cada nombre de clase de atributo debe terminar con esta cadena, pero es válido definir un atributo sin el Attributesufijo -. Al adjuntar un atributo a un elemento, el compilador buscará tanto el nombre literal como el nombre con Attributeagregado al final, es decir, si escribiera [Custom]el compilador buscaría tanto Customcomo CustomAttribute. Si ambos existen, el compilador falla. El atributo puede tener el prefijo " @" si no desea arriesgarse a la ambigüedad, por lo que escribir [@Custom]no coincidirá con CustomAttribute. El uso del atributo invoca el constructor de la clase. Se admiten constructores sobrecargados. Los pares nombre-valor se asignan a propiedades, el nombre denota el nombre de la propiedad y el valor proporcionado es establecido por la propiedad.
A veces existe ambigüedad respecto a qué atributo se está asignando. Considere el siguiente código:
[Naranja] public int ExampleMethod ( string input ) { // el cuerpo del método va aquí }¿Qué se ha marcado como naranja? ¿Es el ExampleMethod, su valor de retorno o quizás todo el ensamblado? En este caso, el compilador actuará por defecto y tratará el atributo como si estuviera adjunto al método. Si esto no es lo que se pretendía, o si el autor desea aclarar su código, se puede especificar un destino de atributo[return: Orange] . Escribir marcará el valor de retorno como naranja, [assembly: Orange]marcará todo el ensamblado. Los destinos válidos son assembly, field, event, method, module, param, property, returny type.
Un atributo pseudo-personalizado se utiliza igual que los atributos personalizados normales, pero no tiene un controlador personalizado; en cambio, el compilador reconoce intrínsecamente los atributos y gestiona el código marcado con ellos de forma diferente. Atributos como Serializabley se implementan como atributos pseudo-personalizados. ILAsmObsolete nunca debería utilizar atributos pseudo-personalizados , ya que dispone de una sintaxis adecuada para describir los metadatos.
Almacenamiento de metadatos
Los ensamblados contienen tablas de metadatos. Estas tablas se describen en la especificación CIL. [ 2 ] Las tablas de metadatos tendrán cero o más entradas, y la posición de una entrada determina su índice. Cuando el código CIL utiliza metadatos, lo hace a través de un token de metadatos. Este es un valor de 32 bits donde los 8 bits superiores identifican la tabla de metadatos correspondiente, y los 24 bits restantes proporcionan el índice de los metadatos en la tabla. El SDK de Framework contiene un ejemplo metainfoque lista las tablas de metadatos en un ensamblado; sin embargo, esta información rara vez es útil para un desarrollador. Los metadatos en un ensamblado se pueden visualizar utilizando la herramienta ILDASM proporcionada por el SDK de .NET Framework .
En el estándar CIL, los metadatos se definen en formato ILAsm (lenguaje ensamblador), en una representación en disco para su almacenamiento y en un formato integrado en los ensamblados del formato ejecutable portátil (PE, .exe o .dll). El formato PE se basa en el formato en disco.
Reflexión
La reflexión es la API que se utiliza para leer los metadatos de la CLI. Esta API proporciona una vista lógica de los metadatos, en lugar de la vista literal que ofrecen herramientas como metainfo. En la versión 1.1 del framework .NET, la reflexión permite inspeccionar las descripciones de las clases y sus miembros, e invocar métodos. Sin embargo, no permite el acceso en tiempo de ejecución al CIL de un método. La versión 2.0 del framework permite obtener el CIL de un método.
Otras herramientas de metadatos
Además del System.Reflectionespacio de nombres, existen otras herramientas para gestionar los metadatos. Microsoft .NET Framework incluye una biblioteca de manipulación de metadatos CLR implementada en código nativo . También se pueden utilizar herramientas de terceros para recuperar y manipular metadatos, como PostSharp y Mono Cecil .
Véase también
Referencias
- Infraestructura de lenguaje común