Condividi tramite


Accesso agli attributi tramite reflection (C# e Visual Basic)

Il fatto di poter definire attributi personalizzati e inserirli nel codice sorgente non sarebbe di grande utilità se non fosse in qualche modo possibile accedere a queste informazioni e modificarle. Tramite la reflection è possibile recuperare le informazioni definite con attributi personalizzati. Il metodo chiave è GetCustomAttributes, che restituisce una matrice di oggetti corrispondenti agli attributi del codice sorgente in fase di esecuzione. Questo metodo dispone di diverse versioni di overload. Per ulteriori informazioni, vedere Attribute.

Una specifica di attributo quale la seguente:

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

equivale concettualmente a quanto segue:

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

Il codice non viene tuttavia eseguito fino a quando non sono stati richiesti gli attributi a SampleClass. Quando si chiama GetCustomAttributes su SampleClass, viene costruito e inizializzato un oggetto Author, come illustrato in precedenza. Se la classe dispone di altri attributi, gli altri oggetti attributo verranno costruiti in modo analogo. GetCustomAttributes restituirà quindi l'oggetto Author e gli eventuali altri oggetti attributo in una matrice. Sarà quindi possibile eseguire iterazioni su questa matrice, determinare quali attributi sono stati applicati in base al tipo di ciascun elemento della matrice ed estrarre informazioni dagli oggetti attributo.

Esempio

Di seguito è riportato un esempio completo. In esso viene definito un attributo personalizzato, che viene quindi applicato a varie entità e recuperato tramite reflection.

' 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
*/

Vedere anche

Riferimenti

Reflection (C# e Visual Basic)

Attributi (C# e Visual Basic)

Creazione di attributi personalizzati (C# e Visual Basic)

System.Reflection

Attribute

Concetti

C# Programming Guide

Recupero di informazioni memorizzate negli attributi

Altre risorse

Visual Basic Programming Guide