Acessando os atributos personalizados

Após atributos associados a elementos do programa, a reflexão pode ser usado para consultar os seus valores e a existência. No.Atributos do NET Framework versão 1.0 e 1.1, personalizados são examinados no contexto de execução. A.NET Framework versão 2.0 fornece um novo contexto de carga, o contexto somente de reflexão, que pode ser usado para examinar o código não pode ser carregado para execução.

O contexto somente de reflexão

Não é possível executar o código carregado no contexto somente de reflexão. Isso significa que não não possível criar instâncias de atributos personalizados, pois isso necessitaria executando seus construtores. Para carregar e examine os atributos personalizados no contexto somente de reflexão, use o CustomAttributeData classe. Você pode obter as instâncias dessa classe usando a sobrecarga apropriada de estática CustomAttributeData.GetCustomAttributes método. Consulte Como: Carregar Assemblies no contexto somente de reflexão.

O contexto de execução

Os métodos de reflexão principais atributos de consulta no contexto de execução são MemberInfo.GetCustomAttributes e Attribute.GetCustomAttributes.

A acessibilidade de um atributo personalizado é verificada em relação ao assembly no qual ele está anexado. Isso equivale a verificar se um método em um tipo no assembly no qual o atributo personalizado é anexado pode chamar o construtor do atributo personalizado.

Métodos como Assembly.GetCustomAttributes(Boolean) Verificar a visibilidade e acessibilidade do argumento de tipo. Somente o código no assembly que contém o tipo definido pelo usuário pode recuperar um atributo personalizado desse tipo usando GetCustomAttributes.

O exemplo a seguir C# é um padrão de design típico de atributo personalizado. Ele ilustra o modelo de reflexão de atributo personalizado de tempo de execução.

System.DLL
public class DescriptionAttribute : Attribute
{
}

System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}

public class LocalizationExtenderProvider
{
    [MyDescriptionAttribute(...)]
    public CultureInfo GetLanguage(...)
    {
    }
}

Se o tempo de execução está tentando recuperar os atributos personalizados para o tipo de atributo personalizado public DescriptionAttribute anexado para o GetLanguage método, ele realiza as seguintes ações:

  1. O runtime verifica que o argumento do tipo DescriptionAttribute para Type.GetCustomAttributes(tipo de tipo de) é pública e, portanto, visíveis e acessíveis.

  2. O runtime verifica que o tipo definido pelo usuário MyDescriptionAttribute que é derivada de DescriptionAttribute estiver visível e acessível dentro do System.Web.DLL assembly, onde ele está conectado ao método GetLanguage().

  3. O runtime verifica que o construtor da MyDescriptionAttribute estiver visível e acessível dentro do System.Web.DLL assembly.

  4. O tempo de execução chama o construtor da MyDescriptionAttribute com os parâmetros de atributo personalizado e retorna o novo objeto para o chamador.

O modelo de reflexão de atributo personalizado pode vazar instâncias de tipos definidos pelo usuário, fora do assembly no qual o tipo é definido. Isso não é diferente de membros na biblioteca do sistema de runtime que retornam instâncias de tipos definidos pelo usuário, como Type.GetMethods() retornar uma matriz de RuntimeMethodInfo objetos. Para impedir que um cliente de descoberta de informações sobre um tipo definido pelo usuário de atributo personalizado, defina os membros do tipo a ser confidenciais.

O exemplo a seguir demonstra a forma básica de usando a reflexão para obter acesso a atributos personalizados.

Imports System

Public Class ExampleAttribute
    Inherits Attribute

    Private stringVal As String

    Public Sub New()
        stringVal = "This is the default string."
    End Sub

    Public Property StringValue() As String
        Get
            Return stringVal
        End Get
        Set(Value As String)
            stringVal = Value
        End Set
    End Property
End Class

<Example(StringValue := "This is a string.")> _
Class Class1
    Public Shared Sub Main()
    Dim info As System.Reflection.MemberInfo = GetType(Class1)
        For Each attrib As Object In info.GetCustomAttributes(true)
            Console.WriteLine(attrib)
        Next attrib
    End Sub
End Class
using System;

public class ExampleAttribute : Attribute
{
    private string stringVal;

    public ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }

    public string StringValue
    {
        get { return stringVal; }
        set { stringVal = value; }
    }
}

[Example(StringValue="This is a string.")]
class Class1
{
    public static void Main()
    {
        System.Reflection.MemberInfo info = typeof(Class1);
        foreach (object attrib in info.GetCustomAttributes(true))
        {
            Console.WriteLine(attrib);
        }
    }
}
using namespace System;

public ref class ExampleAttribute : Attribute
{
private:
    String^ stringVal;

public:
    ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }


    property String^ StringValue
    {
        String^ get() { return stringVal; }
        void set(String^ value) { stringVal = value; }
    }
};

[Example(StringValue="This is a string.")]
public ref class Class1
{
public:
    static void Main()
    {
        System::Reflection::MemberInfo^ info = Type::GetType("Class1");
        for each (Object^ attrib in info->GetCustomAttributes(true))
        {
            Console::WriteLine(attrib);
        }
    }
};

int main()
{
    Class1::Main();
}

Consulte também

Referência

MemberInfo.GetCustomAttributes

Attribute.GetCustomAttributes

Conceitos

Exibindo informações de tipo

Considerações de segurança para reflexão