Acceso a atributos personalizados
Actualización: noviembre 2007
Tras asociar atributos a elementos del programa, se puede utilizar la reflexión para consultar su existencia y sus valores. En las versiones 1.0 y 1.1 de .NET Framework, se examinan los atributos personalizados en el contexto de ejecución. La versión 2.0 de .NET Framework proporciona un nuevo contexto de carga, el contexto de sólo reflexión, que se puede utilizar para examinar código que no puede cargarse para su ejecución.
Contexto de sólo reflexión
El código cargado en el contexto de sólo reflexión no se puede ejecutar. Esto significa que no se pueden crear instancias de atributos personalizados, porque requeriría que se ejecutaran sus constructores. Para cargar y examinar los atributos personalizados en el contexto de sólo reflexión, utilice la clase CustomAttributeData. Puede obtener instancias de esta clase utilizando la sobrecarga adecuada del método CustomAttributeData.GetCustomAttributes estático. Vea Cómo: Cargar ensamblados en el contexto de sólo reflexión.
Contexto de ejecución
Los principales métodos de reflexión para consultar los atributos en el contexto de ejecución son System.Reflection.MemberInfo.GetCustomAttributes y System.Reflection.Assembly.GetCustomAttributes.
La accesibilidad de un atributo personalizado se comprueba con respecto al ensamblado donde se ha anexado. Esto equivale a comprobar si un método en un tipo del ensamblado donde se ha asociado el atributo personalizado puede llamar al constructor de este último.
Los métodos como System.Reflection.Assembly.GetCustomAttributes(Type, Boolean) comprueban la visibilidad y accesibilidad del argumento de tipo. Sólo el código del ensamblado que contiene el tipo definido por el usuario puede recuperar un atributo personalizado de ese tipo utilizando GetCustomAttributes.
El ejemplo siguiente de C# es un modelo de diseño típico de atributos personalizados. En el ejemplo se muestra el modelo de reflexión de atributos personalizados en tiempo de ejecución.
System.DLL
public class DescriptionAttribute : Attribute
{
}
System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}
public class LocalizationExtenderProvider
{
[MyDescriptionAttribute(...)]
public CultureInfo GetLanguage(...)
{
}
}
Si el motor en tiempo de ejecución intenta recuperar los atributos personalizados para el tipo de atributo personalizado público DescriptionAttribute asociado al método GetLanguage, realiza las siguientes acciones:
El motor en tiempo de ejecución comprueba que el argumento de tipo DescriptionAttribute de Type.GetCustomAttributes(Type tipo) es público y, por lo tanto, visible y accesible.
El motor en tiempo de ejecución comprueba que el tipo definido por el usuario SRDescriptionAttribute que se deriva de DescriptionAttribute es visible y accesible en el ensamblado System.Web.DLL, donde está asociada al método GetLanguage().
El motor en tiempo de ejecución comprueba que el constructor de SRDescriptionAttribute es visible y accesible en el ensamblado System.Web.DLL.
El motor en tiempo de ejecución llama al constructor de MyDescriptionAttribute con los parámetros de atributo personalizados y devuelve el nuevo objeto al llamador.
El modelo de reflexión de atributos personalizados puede perder instancias de tipos definidos por el usuario fuera del ensamblado donde se define el tipo. Esto no se diferencia de los miembros en la biblioteca del sistema en tiempo de ejecución que devuelven instancias de tipos definidos por el usuario, como Type.GetMethods() que devuelve una matriz de objetos RuntimeMethodInfo. Para evitar que un cliente descubra información sobre un tipo de atributo personalizado definido por el usuario, defina los miembros del tipo como no públicos.
En el ejemplo siguiente se muestra la forma básica de utilizar la reflexión para obtener acceso a los atributos personalizados.
Class Class1
Public Shared Sub Main()
Dim info As System.Reflection.MemberInfo = GetType(Class1)
Dim attributes() As Object = info.GetCustomAttributes(True)
For i As Integer = 0 To attributes.Length - 1
System.Console.WriteLine(attributes(i))
Next i
End Sub
End Class
class MyClass
{
public static void Main()
{
System.Reflection.MemberInfo info = typeof(MyClass);
object[] attributes = info.GetCustomAttributes(true);
for (int i = 0; i < attributes.Length; i++)
{
System.Console.WriteLine(attributes[i]);
}
}
}
Vea también
Conceptos
Consideraciones de seguridad sobre la reflexión