Partager via


Utiliser des attributs personnalisés

Pour concevoir des attributs personnalisés, vous n’avez pas besoin d’apprendre de nombreux nouveaux concepts. Si vous êtes familiarisé avec la programmation orientée objet et que vous savez comment concevoir des classes, vous avez déjà la plupart des connaissances nécessaires. Les attributs personnalisés sont des classes traditionnelles qui dérivent directement ou indirectement de la System.Attribute classe. Tout comme les classes traditionnelles, les attributs personnalisés contiennent des méthodes qui stockent et récupèrent des données.

Les étapes principales pour concevoir correctement des classes d’attributs personnalisées sont les suivantes :

Cette section décrit chacune de ces étapes et se termine par un exemple d’attribut personnalisé.

Utilisation de l'attribut AttributeUsageAttribute

Une déclaration d’attribut personnalisée commence par l’attribut System.AttributeUsageAttribute , qui définit certaines des caractéristiques clés de votre classe d’attributs. Par exemple, vous pouvez spécifier si votre attribut peut être hérité par d’autres classes ou quels éléments l’attribut peut être appliqué. Le fragment de code suivant montre comment utiliser les AttributeUsageAttributeéléments suivants :

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
<AttributeUsage(AttributeTargets.All, Inherited:=False, AllowMultiple:=True)>
Public Class SomeClass
    Inherits Attribute
    '...
End Class

Le AttributeUsageAttribute a trois membres qui sont importants pour la création d’attributs personnalisés : AttributeTargets, Inherited et AllowMultiple.

Membre AttributeTargets

Dans l’exemple précédent, AttributeTargets.All est spécifié, indiquant que cet attribut peut être appliqué à tous les éléments de programme. Vous pouvez également spécifier AttributeTargets.Class, indiquant que votre attribut ne peut être appliqué qu’à une classe, ou AttributeTargets.Method, indiquant que votre attribut ne peut être appliqué qu’à une méthode. Tous les éléments de programme peuvent être marqués pour la description par un attribut personnalisé de cette façon.

Vous pouvez également passer plusieurs AttributeTargets valeurs. Le fragment de code suivant spécifie qu’un attribut personnalisé peut être appliqué à n’importe quelle classe ou méthode :

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method)>
Public Class SomeOtherClass
    Inherits Attribute
    '...
End Class

Propriété héritée

La AttributeUsageAttribute.Inherited propriété indique si votre attribut peut être hérité par des classes dérivées des classes auxquelles votre attribut est appliqué. Cette propriété prend soit un true (par défaut), soit un indicateur false. Dans l’exemple suivant, MyAttribute a une valeur par défaut de Inherited, tandis que true a une valeur YourAttribute de Inherited.

// This defaults to Inherited = true.
public class MyAttribute : Attribute
{
    //...
}

[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class YourAttribute : Attribute
{
    //...
}
' This defaults to Inherited = true.
Public Class MyAttribute
    Inherits Attribute
    '...
End Class

<AttributeUsage(AttributeTargets.Method, Inherited:=False)>
Public Class YourAttribute
    Inherits Attribute
    '...
End Class

Les deux attributs sont ensuite appliqués à une méthode dans la classe MyClassde base :

public class MyClass
{
    [MyAttribute]
    [YourAttribute]
    public virtual void MyMethod()
    {
        //...
    }
}
Public Class MeClass
    <MyAttribute>
    <YourAttribute>
    Public Overridable Sub MyMethod()
        '...
    End Sub
End Class

Enfin, la classe YourClass est héritée de la classe MyClassde base . La méthode MyMethod affiche MyAttribute , mais pas YourAttribute:

public class YourClass : MyClass
{
    // MyMethod will have MyAttribute but not YourAttribute.
    public override void MyMethod()
    {
        //...
    }
}
Public Class YourClass
    Inherits MeClass
    ' MyMethod will have MyAttribute but not YourAttribute.
    Public Overrides Sub MyMethod()
        '...
    End Sub

End Class

Propriété AllowMultiple

La AttributeUsageAttribute.AllowMultiple propriété indique si plusieurs instances de votre attribut peuvent exister sur un élément. Si la valeur est définie true, plusieurs instances sont autorisées. Si elle est définie false sur (valeur par défaut), une seule instance est autorisée.

Dans l’exemple suivant, MyAttribute a une valeur AllowMultiplepar défaut false , tandis qu’elle YourAttribute a la valeur :true

//This defaults to AllowMultiple = false.
public class MyAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
' This defaults to AllowMultiple = false.
Public Class MyAttribute
    Inherits Attribute
End Class

<AttributeUsage(AttributeTargets.Method, AllowMultiple:=true)>
Public Class YourAttribute
    Inherits Attribute
End Class

Lorsque plusieurs instances de ces attributs sont appliquées, MyAttribute génère une erreur du compilateur. L’exemple de code suivant montre l’utilisation valide de YourAttribute et l’utilisation non valide de MyAttribute :

public class MyClass
{
    // This produces an error.
    // Duplicates are not allowed.
    [MyAttribute]
    [MyAttribute]
    public void MyMethod()
    {
        //...
    }

    // This is valid.
    [YourAttribute]
    [YourAttribute]
    public void YourMethod()
    {
        //...
    }
}
Public Class MyClass
    ' This produces an error.
    ' Duplicates are not allowed.
    <MyAttribute>
    <MyAttribute>
    Public Sub MyMethod()
        '...
    End Sub

    ' This is valid.
    <YourAttribute>
    <YourAttribute>
    Public Sub YourMethod()
        '...
    End Sub
End Class

Si la propriété AllowMultiple et la propriété Inherited sont définies sur true, une classe héritée d'une autre classe peut hériter d'un attribut et recevoir une autre instance du même attribut appliqué dans la même classe enfant. Si AllowMultiple est défini à false, les valeurs de tous les attributs de la classe parente sont remplacées par de nouvelles instances du même attribut dans la classe enfant.

Déclaration de la classe d’attributs

Après avoir appliqué le AttributeUsageAttribute, commencez à définir les spécificités de votre attribut. La déclaration d’une classe d’attribut ressemble à la déclaration d’une classe traditionnelle, comme illustré par le code suivant :

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
    // . . .
}
<AttributeUsage(AttributeTargets.Method)>
Public Class MyAttribute
    Inherits Attribute
    ' . . .
End Class

Cette définition d’attribut illustre les points suivants :

  • Les classes d’attribut doivent être déclarées en tant que classes publiques.

  • Par convention, le nom de la classe d’attribut se termine par le mot Attribut. Bien qu’elle ne soit pas obligatoire, cette convention est recommandée pour la lisibilité. Lorsque l’attribut est appliqué, l’inclusion de l’attribut word est facultative.

  • Toutes les classes d’attribut doivent hériter directement ou indirectement de la System.Attribute classe.

  • Dans Microsoft Visual Basic, toutes les classes d’attributs personnalisées doivent avoir l’attribut System.AttributeUsageAttribute .

Déclaration de constructeurs

Tout comme les classes traditionnelles, les attributs sont initialisés avec des constructeurs. Le fragment de code suivant illustre un constructeur d’attribut classique. Ce constructeur public prend un paramètre et définit une variable membre égale à sa valeur.

public MyAttribute(bool myvalue)
{
    this.myvalue = myvalue;
}
Public Sub New(myvalue As Boolean)
    Me.myvalue = myvalue
End Sub

Vous pouvez surcharger le constructeur pour prendre en charge différentes combinaisons de valeurs. Si vous définissez également une propriété pour votre classe d’attributs personnalisée, vous pouvez utiliser une combinaison de paramètres nommés et positionnels lors de l’initialisation de l’attribut. En règle générale, vous définissez tous les paramètres requis comme positionnel et tous les paramètres facultatifs comme nommés. Dans ce cas, l’attribut ne peut pas être initialisé sans le paramètre requis. Tous les autres paramètres sont facultatifs.

Remarque

Dans Visual Basic, les constructeurs d’une classe d’attribut ne doivent pas utiliser d’argument ParamArray .

L’exemple de code suivant montre comment un attribut qui utilise le constructeur précédent peut être appliqué à l’aide de paramètres facultatifs et obligatoires. Il part du principe que l’attribut a une valeur booléenne requise et une propriété de chaîne facultative.

// One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
public class SomeClass
{
    //...
}
// One required (positional) parameter is applied.
[MyAttribute(false)]
public class SomeOtherClass
{
    //...
}
' One required (positional) and one optional (named) parameter are applied.
<MyAttribute(false, OptionalParameter:="optional data")>
Public Class SomeClass
    '...
End Class

' One required (positional) parameter is applied.
<MyAttribute(false)>
Public Class SomeOtherClass
    '...
End Class

Déclaration des propriétés

Si vous souhaitez définir un paramètre nommé ou fournir un moyen simple de retourner les valeurs stockées par votre attribut, déclarez une propriété. Les propriétés d’attribut doivent être déclarées en tant qu’entités publiques avec une description du type de données qui sera retourné. Définissez la variable qui contiendra la valeur de votre propriété et associez-la aux méthodes get et set. L’exemple de code suivant montre comment implémenter une propriété dans votre attribut :

public bool MyProperty
{
    get {return this.myvalue;}
    set {this.myvalue = value;}
}
Public Property MyProperty As Boolean
    Get
        Return Me.myvalue
    End Get
    Set
        Me.myvalue = Value
    End Set
End Property

Exemple d’attribut personnalisé

Cette section incorpore les informations précédentes et montre comment concevoir un attribut qui documente des informations sur l’auteur d’une section de code. L’attribut de cet exemple stocke le nom et le niveau du programmeur et indique si le code a été examiné. Il utilise trois variables privées pour stocker les valeurs réelles à enregistrer. Chaque variable est représentée par une propriété publique qui obtient et définit les valeurs. Enfin, le constructeur est défini avec deux paramètres requis :

[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : Attribute
{
    // Private fields.
    private string name;
    private string level;
    private bool reviewed;

    // This constructor defines two required parameters: name and level.

    public DeveloperAttribute(string name, string level)
    {
        this.name = name;
        this.level = level;
        this.reviewed = false;
    }

    // Define Name property.
    // This is a read-only attribute.

    public virtual string Name
    {
        get {return name;}
    }

    // Define Level property.
    // This is a read-only attribute.

    public virtual string Level
    {
        get {return level;}
    }

    // Define Reviewed property.
    // This is a read/write attribute.

    public virtual bool Reviewed
    {
        get {return reviewed;}
        set {reviewed = value;}
    }
}
<AttributeUsage(AttributeTargets.All)>
Public Class DeveloperAttribute
    Inherits Attribute
    ' Private fields.
    Private myname As String
    Private mylevel As String
    Private myreviewed As Boolean

    ' This constructor defines two required parameters: name and level.

    Public Sub New(name As String, level As String)
        Me.myname = name
        Me.mylevel = level
        Me.myreviewed = False
    End Sub

    ' Define Name property.
    ' This is a read-only attribute.

    Public Overridable ReadOnly Property Name() As String
        Get
            Return myname
        End Get
    End Property

    ' Define Level property.
    ' This is a read-only attribute.

    Public Overridable ReadOnly Property Level() As String
        Get
            Return mylevel
        End Get
    End Property

    ' Define Reviewed property.
    ' This is a read/write attribute.

    Public Overridable Property Reviewed() As Boolean
        Get
            Return myreviewed
        End Get
        Set
            myreviewed = value
        End Set
    End Property
End Class

Vous pouvez appliquer cet attribut à l’aide du nom complet, DeveloperAttributeou en utilisant le nom abrégé, Developerde l’une des manières suivantes :

[Developer("Joan Smith", "1")]

-or-

[Developer("Joan Smith", "1", Reviewed = true)]
<Developer("Joan Smith", "1")>

-or-

<Developer("Joan Smith", "1", Reviewed := true)>

Le premier exemple montre l’attribut appliqué avec uniquement les paramètres nommés requis. Le deuxième exemple montre l’attribut appliqué avec les paramètres obligatoires et facultatifs.

Voir aussi