Partage via


Récupération des informations stockées dans les attributs

La récupération d’un attribut personnalisé est un processus simple. Tout d’abord, déclarez une instance de l’attribut que vous souhaitez récupérer. Ensuite, utilisez la méthode Attribute.GetCustomAttribute pour initialiser le nouvel attribut à la valeur de l’attribut que vous souhaitez récupérer. Une fois le nouvel attribut initialisé, vous pouvez utiliser ses propriétés pour obtenir les valeurs.

Important

Cet article explique comment récupérer des attributs pour le code chargé dans le contexte d’exécution. Pour récupérer des attributs pour le code chargé dans le contexte de réflexion uniquement, vous devez utiliser la classe CustomAttributeData, comme indiqué dans How to : Load Assemblys into the Reflection-Only Context.

Cette section décrit les méthodes suivantes pour récupérer des attributs :

Récupération d’une instance unique d’un attribut

Dans l’exemple suivant, le DeveloperAttribute (décrit dans la section précédente) est appliqué à la classe MainApp au niveau de la classe. La méthode GetAttribute utilise GetCustomAttribute pour récupérer les valeurs stockées dans DeveloperAttribute au niveau de la classe avant de les afficher dans la console.

using namespace System;
using namespace System::Reflection;
using namespace CustomCodeAttributes;

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

    static void GetAttribute(Type^ t)
    {
        // Get instance of the attribute.
        DeveloperAttribute^ MyAttribute =
            (DeveloperAttribute^) Attribute::GetCustomAttribute(t, DeveloperAttribute::typeid);

        if (MyAttribute == nullptr)
        {
            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);
        }
    }
};
using System;
using System.Reflection;
using CustomCodeAttributes;

[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 (MyAttribute == null)
        {
            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.Reflection
Imports CustomCodeAttributes

<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

L’exécution du programme précédent affiche le texte suivant :

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

Si l’attribut est introuvable, la méthode GetCustomAttribute initialise MyAttribute sur une valeur Null. Cet exemple vérifie MyAttribute pour une telle instance et avertit l’utilisateur si l’attribut est introuvable. Si DeveloperAttribute est introuvable dans l’étendue de la classe, la console affiche le message suivant :

The attribute was not found.

L’exemple précédent suppose que la définition d’attribut se trouve dans l’espace de noms actuel. N’oubliez pas d’importer l’espace de noms dans lequel réside la définition d’attribut si elle n’est pas dans l’espace de noms actuel.

Récupération de plusieurs instances d’un attribut appliqué à la même étendue

Dans l’exemple précédent, la classe à inspecter et l’attribut spécifique à rechercher sont passés à la méthode GetCustomAttribute. Ce code fonctionne correctement si une seule instance d’un attribut est appliquée au niveau de la classe. Toutefois, si plusieurs instances d’un attribut sont appliquées au même niveau de classe, la méthode GetCustomAttribute ne récupère pas toutes les informations. Dans les cas où plusieurs instances du même attribut sont appliquées à la même étendue, vous pouvez utiliser Attribute.GetCustomAttributes méthode pour placer toutes les instances d’un attribut dans un tableau. Par exemple, si deux instances de DeveloperAttribute sont appliquées au niveau de la classe de la même classe, la méthode GetAttribute peut être modifiée pour afficher les informations trouvées dans les deux attributs. N’oubliez pas d’appliquer plusieurs attributs au même niveau. L’attribut doit être défini avec la propriété AllowMultiple définie sur true dans la classe AttributeUsageAttribute.

L’exemple de code suivant montre comment utiliser la méthode GetCustomAttributes pour créer un tableau qui référence toutes les instances de DeveloperAttribute dans une classe donnée. Le code génère ensuite les valeurs de tous les attributs dans la console.

public:
    static void GetAttribute(Type^ t)
    {
        array<DeveloperAttribute^>^ MyAttributes =
            (array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);

        if (MyAttributes->Length == 0)
        {
            Console::WriteLine("The attribute was not found.");
        }
        else
        {
            for (int i = 0 ; i < MyAttributes->Length; i++)
            {
                // Get the Name value.
                Console::WriteLine("The Name Attribute is: {0}." , MyAttributes[i]->Name);
                // Get the Level value.
                Console::WriteLine("The Level Attribute is: {0}." , MyAttributes[i]->Level);
                // Get the Reviewed value.
                Console::WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i]->Reviewed);
            }
        }
    }
public static void GetAttribute(Type t)
{
    DeveloperAttribute[] MyAttributes =
        (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));

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

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

Si aucun attribut n’est trouvé, ce code alerte l’utilisateur. Sinon, les informations contenues dans les deux instances de DeveloperAttribute sont affichées.

Récupération de plusieurs instances d’un attribut appliqué à différentes étendues

Les méthodes GetCustomAttributes et GetCustomAttribute ne recherchent pas dans une classe entière et retournent toutes les instances d’un attribut dans cette classe. Au lieu de cela, ils ne recherchent qu’une seule méthode ou membre spécifiée à la fois. Si vous avez une classe avec le même attribut appliqué à chaque membre et que vous souhaitez récupérer les valeurs dans tous les attributs appliqués à ces membres, vous devez fournir chaque méthode ou membre individuellement pour GetCustomAttributes et GetCustomAttribute.

L’exemple de code suivant prend une classe en tant que paramètre et recherche le DeveloperAttribute (défini précédemment) au niveau de la classe et sur chaque méthode individuelle de cette 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, DeveloperAttribute::typeid);

        if (att == nullptr)
        {
            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.
        array<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], DeveloperAttribute::typeid);
            if (att == nullptr)
            {
                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 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 (att == null)
    {
        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 (att == null)
        {
            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
        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)
    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.
    For i As Integer = 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}.\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)
        End If
    Next
End Sub

Si aucune instance du DeveloperAttribute n’est trouvée au niveau de la méthode ou de la classe, la méthode GetAttribute informe l’utilisateur qu’aucun attribut n’a été trouvé et affiche le nom de la méthode ou de la classe qui ne contient pas l’attribut. Si un attribut est trouvé, la console affiche les champs Name, Levelet Reviewed.

Vous pouvez utiliser les membres de la classe Type pour obtenir les méthodes individuelles et les membres de la classe transmise. Cet exemple interroge d’abord l’objet Type pour obtenir des informations d’attribut pour le niveau de classe. Ensuite, il utilise Type.GetMethods pour placer des instances de toutes les méthodes dans un tableau d’objets System.Reflection.MemberInfo pour récupérer des informations d’attribut pour le niveau de méthode. Vous pouvez également utiliser la méthode Type.GetProperties pour rechercher des attributs au niveau de la propriété ou Type.GetConstructors pour rechercher des attributs au niveau du constructeur.

Récupération d’attributs à partir de membres de classe

Outre la récupération d’attributs au niveau de la classe, les attributs peuvent également être appliqués à des membres individuels tels que des méthodes, des propriétés et des champs. Les méthodes GetCustomAttribute et GetCustomAttributes peuvent être utilisées pour récupérer ces attributs.

Exemple

L’exemple suivant montre comment récupérer un attribut appliqué à une méthode :

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
    public string Description { get; }
    public MyAttribute(string description) { Description = description; }
}

public class MyClass
{
    [MyAttribute("This is a sample method.")]
    public void MyMethod() { }
}

class AttributeRetrieval
{
    public static void Main()
    {
        // Create an instance of MyClass
        MyClass myClass = new MyClass();

        // Retrieve the method information for MyMethod
        MethodInfo methodInfo = typeof(MyClass).GetMethod("MyMethod");
        MyAttribute attribute = (MyAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(MyAttribute));

        if (attribute != null)
        {
            // Print the description of the method attribute
            Console.WriteLine("Method Attribute: {0}", attribute.Description);
        }
        else
        {
            Console.WriteLine("Attribute not found.");
        }
    }
}

Voir aussi