Uzyskiwanie dostępu do atrybutów przy użyciu odbicia

Fakt, że można zdefiniować atrybuty niestandardowe i umieścić je w kodzie źródłowym, będzie miał niewielką wartość bez konieczności pobierania tych informacji i działania na nim. Przy użyciu odbicia można pobrać informacje zdefiniowane za pomocą atrybutów niestandardowych. Metoda klucza to GetCustomAttributes, która zwraca tablicę obiektów, które są odpowiednikami czasu wykonywania atrybutów kodu źródłowego. Ta metoda ma wiele przeciążonych wersji. Aby uzyskać więcej informacji, zobacz Attribute.

Specyfikacja atrybutu, taka jak:

[Author("P. Ackerman", Version = 1.1)]
class SampleClass { }

jest koncepcyjnie odpowiednikiem następującego kodu:

var anonymousAuthorObject = new Author("P. Ackerman")
{
    Version = 1.1
};

Jednak kod nie jest wykonywany, dopóki SampleClass nie zostanie wykonane zapytanie o atrybuty. Wywołanie metody powoduje AuthorSampleClass konstruowanie GetCustomAttributes i inicjowanie obiektu. Jeśli klasa ma inne atrybuty, inne obiekty atrybutów są konstruowane podobnie. GetCustomAttributes następnie zwraca Author obiekt i wszystkie inne obiekty atrybutów w tablicy. Następnie można iterować na tej tablicy, określić, jakie atrybuty zostały zastosowane na podstawie typu każdego elementu tablicy i wyodrębnić informacje z obiektów atrybutów.

Oto kompletny przykład. Atrybut niestandardowy jest definiowany, stosowany do kilku jednostek i pobierany za pośrednictwem odbicia.

// Multiuse attribute.
[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)  // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{
    string Name;
    public double Version;

    public AuthorAttribute(string name)
    {
        Name = name;

        // Default value.
        Version = 1.0;
    }

    public string GetName() => 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
{
    public 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 {t}");

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

        // Displaying output.
        foreach (System.Attribute attr in attrs)
        {
            if (attr is AuthorAttribute a)
            {
                System.Console.WriteLine($"   {a.GetName()}, version {a.Version:f}");
            }
        }
    }
}
/* 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
*/

Zobacz też