Partilhar via


Acessar atributos usando reflexão (C# e Visual Basic)

O fato de que você pode definir atributos personalizados e colocá-los em seu código-fonte seria de pouco valor sem alguma forma de recuperar essas informações e agindo sobre ele. Usando a reflexão, você pode recuperar as informações que foi definidas com atributos personalizados. O método principal é GetCustomAttributes, que retorna uma matriz de objetos que são os equivalentes de tempo de execução de atributos de código de origem. Este método tem várias versões sobrecarregadas. Para obter mais informações, consulte Attribute.

Uma especificação de atributo, como:

<Author("P. Ackerman", Version:=1.1)> 
Class SampleClass
    ' P. Ackerman's code goes here...
End Class
[Author("P. Ackerman", version = 1.1)]
class SampleClass

Conceitualmente, equivale a este:

Dim anonymousAuthorObject As Author = New Author("P. Ackerman")
anonymousAuthorObject.version = 1.1
Author anonymousAuthorObject = new Author("P. Ackerman");
anonymousAuthorObject.version = 1.1;

No entanto, o código não será executado até que SampleClass é consultado para atributos. Chamando GetCustomAttributes em SampleClass faz com que uma Author objeto seja construído e inicializado como acima. Se a classe tem outros atributos, outros objetos de atributo são construídos da mesma forma. GetCustomAttributesem seguida, retorna o Author objeto e quaisquer outros objetos de atributo em uma matriz. Você pode iterar sobre essa matriz, determinar quais atributos foram aplicados com base no tipo de cada elemento da matriz e extrair informações de objetos de atributos.

Exemplo

Aqui está um exemplo completo. Um atributo personalizado é definido, aplicado a várias entidades e recuperado por meio de reflexão.

' Multiuse attribute
<System.AttributeUsage(System.AttributeTargets.Class Or 
                       System.AttributeTargets.Struct, 
                       AllowMultiple:=True)> 
Public Class Author
    Inherits System.Attribute
    Private name As String
    Public version As Double
    Sub New(ByVal authorName As String)
        name = authorName

        ' Default value
        version = 1.0
    End Sub

    Function GetName() As String
        Return name
    End Function        
End Class

' Class with the Author attribute
<Author("P. Ackerman")> 
Public Class FirstClass
End Class

' Class without the Author attribute
Public Class SecondClass
End Class

' Class with multiple Author attributes.
<Author("P. Ackerman"), Author("R. Koch", Version:=2.0)> 
Public Class ThirdClass
End Class

Class TestAuthorAttribute
    Sub Main()
        PrintAuthorInfo(GetType(FirstClass))
        PrintAuthorInfo(GetType(SecondClass))
        PrintAuthorInfo(GetType(ThirdClass))
    End Sub

    Private Shared Sub PrintAuthorInfo(ByVal t As System.Type)
        System.Console.WriteLine("Author information for {0}", t)

        ' Using reflection
        Dim attrs() As System.Attribute = System.Attribute.GetCustomAttributes(t)

        ' Displaying output
        For Each attr In attrs
            Dim a As Author = CType(attr, Author)
            System.Console.WriteLine("   {0}, version {1:f}", a.GetName(), a.version)
        Next            
    End Sub

    ' Output:
    '   Author information for FirstClass
    '     P. Ackerman, version 1.00
    ' Author information for SecondClass
    ' Author information for ThirdClass
    '  R. Koch, version 2.00
    '  P. Ackerman, version 1.00

End Class
// Multiuse attribute.
[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)  // Multiuse attribute.
]
public class Author : System.Attribute
{
    string name;
    public double version;

    public Author(string name)
    {
        this.name = name;

        // Default value.
        version = 1.0;
    }

    public string GetName()
    {
        return name;
    }
}

// Class with the Author attribute.
[Author("P. Ackerman")]
public class FirstClass
{
    // ...
}

// Class without the Author attribute.
public class SecondClass
{
    // ...
}

// Class with multiple Author attributes.
[Author("P. Ackerman"), Author("R. Koch", version = 2.0)]
public class ThirdClass
{
    // ...
}

class TestAuthorAttribute
{
    static void Test()
    {
        PrintAuthorInfo(typeof(FirstClass));
        PrintAuthorInfo(typeof(SecondClass));
        PrintAuthorInfo(typeof(ThirdClass));
    }

    private static void PrintAuthorInfo(System.Type t)
    {
        System.Console.WriteLine("Author information for {0}", t);

        // Using reflection.
        System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // Reflection.

        // Displaying output.
        foreach (System.Attribute attr in attrs)
        {
            if (attr is Author)
            {
                Author a = (Author)attr;
                System.Console.WriteLine("   {0}, version {1:f}", a.GetName(), a.version);
            }
        }
    }
}
/* Output:
    Author information for FirstClass
       P. Ackerman, version 1.00
    Author information for SecondClass
    Author information for ThirdClass
       R. Koch, version 2.00
       P. Ackerman, version 1.00
*/

Consulte também

Referência

Reflexão (C# e Visual Basic)

Atributos (C# e Visual Basic)

Criando os atributos personalizados (C# e Visual Basic)

System.Reflection

Attribute

Conceitos

Guia de Programação C#

Recuperando Informações Armazenadas em Atributos

Outros recursos

Guia de programação Visual Basic