Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los atributos proporcionan una manera eficaz de asociar metadatos, o información declarativa, con código (ensamblados, tipos, métodos, propiedades, etc.). Después de asociar un atributo a una entidad de programa, puede consultar el atributo en tiempo de ejecución mediante una técnica denominada reflexión.
Los atributos tienen las siguientes propiedades:
- Los atributos agregan metadatos al programa. Metadatos son información sobre los tipos definidos en un programa. Todos los ensamblados de .NET contienen un conjunto especificado de metadatos que describe los tipos y miembros de tipo definidos en el ensamblado. Puede agregar atributos personalizados para especificar cualquier otra información necesaria.
- Los atributos se pueden aplicar a ensamblados, módulos o elementos de programa más pequeños, como clases y propiedades.
- Los atributos pueden aceptar argumentos de la misma manera que los métodos y propiedades.
- Los atributos permiten a un programa examinar sus propios metadatos o metadatos en otros programas mediante la reflexión.
Trabajar con reflexión
Reflexión Las API proporcionadas por Type describen ensamblados, módulos y tipos. Puede usar la reflexión para crear dinámicamente una instancia de un tipo, enlazar el tipo a un objeto existente o obtener el tipo de un objeto existente e invocar sus métodos o acceder a sus campos y propiedades. Al usar atributos en el código, la reflexión le permite acceder a ellos. Para obtener más información, vea atributos de .
Este es un ejemplo sencillo de reflexión con el GetType() método . Todos los tipos de la Object
clase base heredan este método, que se usa para obtener el tipo de una variable:
Nota
Asegúrese de agregar las declaraciones using System;
y using System.Reflection;
en la parte superior de su archivo de código C# (.cs).
// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);
La salida muestra el tipo:
System.Int32
En el ejemplo siguiente se usa la reflexión para obtener el nombre completo del ensamblado cargado.
// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);
La salida es similar a la del ejemplo siguiente:
System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Diferencias de palabras clave para IL
Las palabras clave protected
de C# y internal
no tienen ningún significado en el lenguaje intermedio (IL) y no se usan en las API de reflexión. Los términos correspondientes en IL son Family y Assembly. Estas son algunas maneras de usar estos términos:
- Para identificar un
internal
método mediante la reflexión, use la IsAssembly propiedad . - Para identificar un método
protected internal
, use IsFamilyOrAssembly.
Trabajar con atributos
Los atributos se pueden colocar en casi cualquier declaración, aunque un atributo específico podría restringir los tipos de declaraciones en las que es válido. En C#, especifique un atributo colocando el nombre del atributo entre corchetes ([]
) encima de la declaración de la entidad a la que se aplica.
En este ejemplo, se usa el SerializableAttribute atributo para aplicar una característica específica a una clase :
[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
Puede declarar un método con el DllImportAttribute atributo :
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
Puede colocar varios atributos en una declaración:
void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }
Algunos atributos se pueden especificar más de una vez para una entidad determinada. En el ejemplo siguiente se muestra la multiuso del ConditionalAttribute atributo :
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
Nota
Por convención, todos los nombres de atributo terminan con el sufijo "Attribute" para distinguirlos de otros tipos de las bibliotecas de .NET. Sin embargo, no es necesario especificar el sufijo de atributo al usar atributos en el código. Por ejemplo, una [DllImport]
declaración es equivalente a una [DllImportAttribute]
declaración, pero DllImportAttribute
es el nombre real de la clase en la biblioteca de clases de .NET.
Parámetros de atributo
Muchos atributos tienen parámetros, que pueden ser posicionales, sin nombre o con nombre. La siguiente tabla describe cómo trabajar con atributos nominales y posicionales.
Parámetros posicionales
Parámetros del constructor de atributos:
Parámetros con nombre
Propiedades o campos del atributo:
- Debe especificar, no se puede omitir
- Siempre especificar primero
- Especifica en determinado orden
- Siempre opcional, omitir cuando es falso
- Especificar después de los parámetros de posición
- Especificar en cualquier orden
Por ejemplo, el código siguiente muestra tres atributos equivalentes DllImport
:
[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
El primer parámetro, el nombre del archivo DLL, es posicional y siempre viene primero. Las otras instancias son parámetros con nombre. En este escenario, ambos parámetros con nombre tienen como valor predeterminado false, por lo que se pueden omitir. Consulte la documentación del atributo individual para obtener información sobre los valores de parámetro predeterminados. Para obtener más información sobre los tipos de parámetros permitidos, consulte la sección Atributos de de la especificación del lenguaje C# .
Destinos de atributo
El destino de un atributo es la entidad a la que se aplica el atributo. Por ejemplo, un atributo se puede aplicar a una clase, un método o un ensamblado. De forma predeterminada, un atributo se aplica al elemento que lo sigue. Pero también puede identificar explícitamente el elemento que se va a asociar, como un método, un parámetro o el valor devuelto.
Para identificar explícitamente un destino de atributo, use la sintaxis siguiente:
[target : attribute-list]
En la tabla siguiente se muestra la lista de valores posibles target
.
Valor del objetivo | Se aplica a |
---|---|
assembly |
Ensamblado completo |
module |
Módulo de ensamblado actual |
field |
Campo de una clase o un struct |
event |
Evento |
method |
Método o descriptores de acceso de propiedad get y set |
param |
Parámetros de método o parámetros de descriptor de acceso de propiedad set |
property |
Propiedad |
return |
Valor devuelto de un método, indexador de propiedad o descriptor de acceso de propiedad get |
type |
Estructura, clase, interfaz, enumeración o delegado |
Puede especificar el field
valor de destino para aplicar un atributo al campo de respaldo creado para una propiedad implementada automáticamente.
En el ejemplo siguiente se muestra cómo aplicar atributos a ensamblados y módulos. Para obtener más información, vea Atributos comunes (C#).
using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]
En el ejemplo siguiente se muestra cómo aplicar atributos a métodos, parámetros de método y valores devueltos de método en C#.
// default: applies to method
[ValidatedContract]
int Method1() { return 0; }
// applies to method
[method: ValidatedContract]
int Method2() { return 0; }
// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }
// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }
Nota
Independientemente de los destinos en los que se defina que el ValidatedContract
atributo sea válido, el return
destino debe especificarse, aunque el ValidatedContract
atributo se defina para que se aplique solo a los valores devueltos. En otras palabras, el compilador no usa la AttributeUsage
información para resolver destinos de atributo ambiguos. Para obtener más información, vea AttributeUsage.
Revisión de formas de usar atributos
Estas son algunas formas comunes de usar atributos en el código:
- Marque los métodos de controlador que responden a los mensajes POST mediante el
HttpPost
atributo . Para obtener más información, vea la clase HttpPostAttribute. - Describir cómo gestionar los parámetros de métodos al interoperar con código nativo. Para obtener más información, vea la clase MarshalAsAttribute.
- Describir las propiedades del modelo de objetos componentes (COM) para clases, métodos e interfaces.
- Llamar al código no administrado mediante la clase DllImportAttribute.
- Describa el ensamblado en términos de título, versión, descripción o marca comercial.
- Describir qué miembros de una clase serializar para la persistencia.
- Describir cómo asociar los miembros de clase con los nodos XML para la serialización XML.
- Describir los requisitos de seguridad de los métodos.
- Especifique las características usadas para aplicar la seguridad.
- Optimizaciones de control con el compilador Just-In-Time (JIT), por lo que el código sigue siendo fácil de depurar.
- Obtener información sobre el llamador de un método.
Revisar escenarios de reflexión
La reflexión es útil en los escenarios siguientes:
- Obtener acceso a atributos en los metadatos del programa. Para obtener más información, consulte Recuperación de información almacenada en atributos.
- Examinar e instanciar tipos en un ensamblado.
- Crear nuevos tipos en tiempo de ejecución mediante clases en el espacio de nombres System.Reflection.Emit.
- Llevar a cabo métodos de acceso de enlace en tiempo de ejecución en tipos creados en tiempo de ejecución. Para obtener más información, consulte Carga dinámica y uso de tipos.