Recuperando Informações Armazenadas em Atributos

Recuperar um atributo personalizado é um processo simples.Primeiro, declare uma instância do atributo que você deseja recuperar.Em seguida, use o método Attribute.GetCustomAttribute para inicializar o novo atributo com valor do atributo que você deseja recuperar.Depois que o novo atributo é inicializado, você simplesmente usa suas propriedades para obter os valores.

Observação importante:

Este tópico descreve como recuperar os atributos de código carregado no contexto de execução.Para recuperar os atributos de código carregado no contexto somente de reflexão, você deve usar o CustomAttributeData classe, conforme mostrado na Como: Carregar assemblies para o contexto somente de Reflexo.

Esta seção descreve as seguintes maneiras para recuperar os atributos:

  • Recuperando uma única instância de um atributo

  • Recuperando várias instâncias de um atributo aplicada ao mesmo escopo

  • Recuperando várias instâncias de um atributo aplicadas a diferentes escopos

Recuperando uma única instância de um atributo

No exemplo a seguir, o DeveloperAttribute (descrito na seção anterior) é aplicado à classe MainApp no nível de classe.O método GetAttribute usa GetCustomAttribute para recuperar os valores armazenados no DeveloperAttribute no nível de classe antes de exibi-los no console.

using System;

[Developer("Joan Smith", "42", Reviewed = true)]
class MainApp
{
    public static void Main() 
    {
        //Call function to get and display the attribute.
        GetAttribute(typeof(MainApp));
    }

    public static void GetAttribute(Type t) 
    {


        //Get instance of the attribute.    
            DeveloperAttribute MyAttribute = (DeveloperAttribute) Attribute.GetCustomAttribute(t, typeof (DeveloperAttribute));

            if(null == MyAttribute)
            {
                Console.WriteLine("The attribute was not found.");
            }
            else
            {
                //Get the Name value.    
                Console.WriteLine("The Name Attribute is: {0}." , MyAttribute.Name);
                //Get the Level value.    
                Console.WriteLine("The Level Attribute is: {0}." , MyAttribute.Level);
                //Get the Reviewed value.
                Console.WriteLine("The Reviewed Attribute is: {0}." , MyAttribute.Reviewed);
            }
    }
}
Imports System

<Developer("Joan Smith", "42", Reviewed := True)> Class MainApp

    Public Shared Sub Main()
        'Call function to get and display the attribute.
        GetAttribute(GetType(MainApp))
    End Sub

    Public Shared Sub GetAttribute(t As Type)        

        'Get instance of the attribute.
        Dim MyAttribute As DeveloperAttribute = _
        CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)

        If MyAttribute Is Nothing Then
            Console.WriteLine("The attribute was not found.")
        Else
            'Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}.", MyAttribute.Name)
            'Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}.", MyAttribute.Level)
            'Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute.Reviewed)
        End If
    End Sub
End Class

Este programa exibe o texto a seguir quando executado.

The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.

Se o atributo não for encontrado, o método GetCustomAttribute inicializa MyAttribute como um valor nulo.Este exemplo marca MyAttribute para uma instância e notifica o usuário se não for encontrado nenhum atributo.Se o DeveloperAttribute não for encontrado no escopo de classe, a mensagem a seguir é exibida no console.

The attribute was not found. 

Este exemplo pressupõe que a definição de atributo está no atual namespace.Lembre-se de importar o namespace no qual reside a definição de atributo se ele não estiver no atual namespace.

Recuperando várias instâncias de um atributo aplicadas ao mesmo escopo.

No exemplo anterior, a classe para inspecionar e o atributo específico para localizar são passados para GetCustomAttribute.Esse código funciona bem se apenas uma instância de um atributo é aplicada no nível de classe.No entanto, se várias instâncias de um atributo forem aplicadas no mesmo nível de classe, o método GetCustomAttribute não recupera todas as informações.Em casos onde várias instâncias do mesmo atributo são aplicadas ao mesmo escopo, você pode usar Attribute.GetCustomAttributes para colocar todas as instâncias de um atributo em uma matriz.Por exemplo, se duas instâncias de DeveloperAttribute forem aplicadas no nível de classe da mesma classe, o método GetAttribute pode ser modificado para exibir as informações encontradas em ambos os atributos.Lembre-se de que, para aplicar vários atributos no mesmo nível, o atributo deve ser definido com a propriedade AllowMultiple definida como true na caixa AttributeUsageAttribute.

O exemplo de código a seguir mostra como usar o método GetCustomAttributes para criar uma matriz que faz referência a todas as instâncias de DeveloperAttribute em qualquer determinada classe.Em seguida, os valores de todos os atributos são exibidos ao console.

public static void GetAttribute(Type t)
{
    DeveloperAttribute[] MyAttribute =
    (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));

    if(null == MyAttribute)
    {
        Console.WriteLine("The attribute was not found.");
    }
    else
    {
        for(int i = 0 ; i < MyAttribute.Length ; i++)
        {
            //Get the Name value.    
            Console.WriteLine("The Name Attribute is: {0}." , MyAttribute[i].Name);
            //Get the Level value.  
            Console.WriteLine("The Level Attribute is: {0}." , MyAttribute[i].Level);
            //Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute[i].Reviewed);
        }
    }
}
Public Shared Sub GetAttribute(t As Type)
    Dim MyAttribute As DeveloperAttribute() = _
    CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())

    If MyAttribute Is Nothing Then
        Console.WriteLine("The attribute was not found.")
    Else
        Dim i As Integer
        For i = 0 To MyAttribute.Length - 1
            'Get the Name value. 
            Console.WriteLine("The Name Attribute is: {0}.", MyAttribute(i).Name)
            'Get the Level value.   
            Console.WriteLine("The Level Attribute is: {0}.", MyAttribute(i).Level)
            'Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute(i).Reviewed)
        Next i
    End If
End Sub

Se nenhum atributo for encontrado, esse código alerta o usuário.Caso contrário, as informações contidas em ambas as instâncias de DeveloperAttribute são exibidas.

Recuperando várias instâncias de um atributo aplicadas a diferentes escopos

Os métodos GetCustomAttributes e GetCustomAttribute não pesquisam uma classe inteira e retornam todas as instâncias de um atributo na classe.Em vez disso, eles pesquisam somente um método especificado ou um membro de cada vez.Se você tiver uma classe com o mesmo atributo aplicado a cada membro e você deseja recuperar os valores em todos os atributos aplicados a esses participantes, você deve fornecer cada método ou membro individualmente para GetCustomAttributes e GetCustomAttribute.

O exemplo de código a seguir usa uma classe como um parâmetro e procura pela DeveloperAttribute (definida anteriormente) no nível de classe e em cada método individual de classe.

public static void GetAttribute(Type t) 
{

    DeveloperAttribute att;

    //Get the class-level attributes.

    //Put the instance of the attribute on the class level in the att object.
    att = (DeveloperAttribute) Attribute.GetCustomAttribute (t, typeof (DeveloperAttribute));

    if(null == att)
    {
        Console.WriteLine("No attribute in class {0}.\n", t.ToString());
    }
    else
    {
        Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name);
       Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level);
       Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed);
    }   

    //Get the method-level attributes.

    //Get all methods in this class, and put them
    //in an array of System.Reflection.MemberInfo objects.
    MemberInfo[] MyMemberInfo = t.GetMethods();

    //Loop through all methods in this class that are in the 
    //MyMemberInfo array.
    for(int i = 0; i < MyMemberInfo.Length; i++)
    {        
        att = (DeveloperAttribute) Attribute.GetCustomAttribute(MyMemberInfo[i], typeof (DeveloperAttribute));
        if(null == att)
        {
            Console.WriteLine("No attribute in member function {0}.\n" , MyMemberInfo[i].ToString());
        }
        else
        {
            Console.WriteLine("The Name Attribute for the {0} member is: {1}.", MyMemberInfo[i].ToString(), att.Name);
            Console.WriteLine("The Level Attribute for the {0} member is: {1}.", MyMemberInfo[i].ToString(), att.Level);
            Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n", MyMemberInfo[i].ToString(), att.Reviewed);
        }        
    }
}
Public Shared Sub GetAttribute(t As Type)

    Dim att As DeveloperAttribute

    'Get the class-level attributes.
    'Put the instance of the attribute on the class level in the att object.
    att = CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)

    If att Is Nothing Then
        Console.WriteLine("No attribute in class {0}.", t.ToString())
        Console.WriteLine()
    Else
        Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name)
        Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level)
        Console.WriteLine("The Reviewed Attribute on the class level is: {0}.", att.Reviewed)
        Console.WriteLine()
    End If

    'Get the method-level attributes.
    'Get all methods in this class and put them
    'in an array of System.Reflection.MemberInfo objects.
    Dim MyMemberInfo As MemberInfo() = t.GetMethods()

    'Loop through all methods in this class that are in the 
    'MyMemberInfo array.
    Dim i As Integer
    For i = 0 To MyMemberInfo.Length - 1
        att = CType(Attribute.GetCustomAttribute(MyMemberInfo(i), GetType(DeveloperAttribute)), DeveloperAttribute)
        If att Is Nothing Then
            Console.WriteLine("No attribute in member function {0}.", MyMemberInfo(i).ToString())
            Console.WriteLine()
        Else
            Console.WriteLine("The Name Attribute for the {0} member is: {1}.", MyMemberInfo(i).ToString(), att.Name)
            Console.WriteLine("The Level Attribute for the {0} member is: {1}.", MyMemberInfo(i).ToString(), att.Level)
            Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.", MyMemberInfo(i).ToString(), att.Reviewed)
            Console.WriteLine()
        End If
    Next i
End Sub

Se nenhuma instância de DeveloperAttribute for encontrada no nível de método ou nível de classe, o método GetAttribute notifica o usuário que nenhum atributo foi encontrado e exibe o nome do metódo ou da classe que não contém o atributo.Se um atributo for encontrado, os campos Name,Level e Reviewed são exibidos no console.

Você pode usar os membros da classe Type para obter os métodos e membros individuais na classe passada.Este exemplo primeiro consulta o objeto Type para obter informações de atributo para o nível de classe.Em seguida, ele usa Type.GetMethods para colocar instâncias de todos os métodos em uma matriz de objetos System.Reflection.MemberInfo para recuperar informações de atributo para o nível do método.Você também pode usar o método Type.GetProperties para verificar os atributos no nível de propriedades ou Type.GetConstructors para verificar os atributos no nível do construtor.

Consulte também

Referência

System.Type

Attribute.GetCustomAttribute

Attribute.GetCustomAttributes

Outros recursos

Estendendo metadados usando atributos