Teilen über


Schreiben benutzerdefinierter Attribute

Um benutzerdefinierte Attribute zu entwerfen, müssen Sie nicht viele neue Konzepte erlernen. Wenn Sie mit der objektorientierten Programmierung vertraut sind und wissen, wie Sie Klassen entwerfen, verfügen Sie bereits über die meisten erforderlichen Kenntnisse. Benutzerdefinierte Attribute sind herkömmliche Klassen, die direkt oder indirekt von der System.Attribute Klasse abgeleitet werden. Genau wie herkömmliche Klassen enthalten benutzerdefinierte Attribute Methoden, die Daten speichern und abrufen.

Die primären Schritte zum ordnungsgemäßen Entwerfen von benutzerdefinierten Attributklassen lauten wie folgt:

In diesem Abschnitt werden die einzelnen Schritte beschrieben und mit einem benutzerdefinierten Attributbeispiel abgeschlossen.

Anwenden des AttributeUsageAttribute

Eine benutzerdefinierte Attributdeklaration beginnt mit dem System.AttributeUsageAttribute Attribut, das einige der wichtigsten Merkmale Ihrer Attributklasse definiert. Sie können z. B. angeben, ob Ihr Attribut von anderen Klassen geerbt werden kann oder auf welche Elemente das Attribut angewendet werden kann. Das folgende Codefragment veranschaulicht, wie man AttributeUsageAttribute verwendet.

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

Dies AttributeUsageAttribute umfasst drei Elemente, die für die Erstellung von benutzerdefinierten Attributen wichtig sind: AttributeTargets, Inherited und AllowMultiple.

AttributTargets-Element

Im vorherigen Beispiel wird angegeben, AttributeTargets.All dass dieses Attribut auf alle Programmelemente angewendet werden kann. Alternativ können Sie angeben AttributeTargets.Class, dass Ihr Attribut nur auf eine Klasse angewendet werden kann, oder AttributeTargets.Methodsie gibt an, dass Ihr Attribut nur auf eine Methode angewendet werden kann. Alle Programmelemente können auf diese Weise durch ein benutzerdefiniertes Attribut zur Beschreibung gekennzeichnet werden.

Sie können auch mehrere AttributeTargets Werte übergeben. Das folgende Codefragment gibt an, dass ein benutzerdefiniertes Attribut auf eine beliebige Klasse oder Methode angewendet werden kann:

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

geerbte Eigenschaft

Die AttributeUsageAttribute.Inherited Eigenschaft gibt an, ob Ihr Attribut von Klassen geerbt werden kann, die von den Klassen abgeleitet werden, auf die Ihr Attribut angewendet wird. Diese Eigenschaft verwendet entweder die Standardeinstellung true oder das false-Flag. Im folgenden Beispiel hat MyAttribute einen Standardwert Inherited von true, während YourAttribute einen Inherited Wert von false hat:

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

Die beiden Attribute werden dann auf eine Methode in der Basisklasse MyClassangewendet:

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

Schließlich wird die Klasse YourClass von der Basisklasse MyClassgeerbt. Die Methode MyMethod zeigt MyAttribute , aber nicht 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

AllowMultiple-Eigenschaft

Die AttributeUsageAttribute.AllowMultiple Eigenschaft gibt an, ob mehrere Instanzen Ihres Attributs in einem Element vorhanden sein können. Wenn auf true gesetzt, sind mehrere Instanzen zulässig. Bei Festlegung auf false (Standardeinstellung) ist nur eine Instanz zulässig.

Im folgenden Beispiel hat MyAttribute einen Standardwert AllowMultiple von false, während YourAttribute einen Wert von true hat.

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

Wenn mehrere Instanzen dieser Attribute angewendet werden, erzeugt MyAttribute einen Compilerfehler. Das folgende Codebeispiel zeigt die gültige Verwendung von YourAttribute und die ungültige Verwendung von 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

Wenn sowohl die AllowMultiple-Eigenschaft als auch die Inherited-Eigenschaft auf true festgelegt sind, kann eine Klasse, die von einer anderen Klasse erbt, ein Attribut übernehmen und eine weitere Instanz desselben Attributs in derselben Kindklasse anwenden. Wenn AllowMultiple auf false festgelegt ist, werden die Werte aller Attribute in der übergeordneten Klasse durch neue Instanzen desselben Attributs in der untergeordneten Klasse überschrieben.

Deklarieren der Attributklasse

Nachdem Sie das AttributeUsageAttributeAttribut angewendet haben, definieren Sie zunächst die Besonderheiten Ihres Attributs. Die Deklaration einer Attributklasse ähnelt der Deklaration einer herkömmlichen Klasse, wie im folgenden Code veranschaulicht:

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

Diese Attributdefinition veranschaulicht die folgenden Punkte:

  • Attributklassen müssen als öffentliche Klassen deklariert werden.

  • Standardmäßig endet der Name der Attributklasse mit dem Wort "Attribut". Obwohl nicht erforderlich, wird diese Konvention zur Lesbarkeit empfohlen. Wenn das Attribut angewendet wird, ist die Einbeziehung des Worts "Attribut" optional.

  • Alle Attributklassen müssen direkt oder indirekt von der System.Attribute Klasse erben.

  • In Microsoft Visual Basic müssen alle benutzerdefinierten Attributklassen das System.AttributeUsageAttribute Attribut aufweisen.

Deklarieren von Konstruktoren

Genau wie herkömmliche Klassen werden Attribute mit Konstruktoren initialisiert. Das folgende Codefragment veranschaulicht einen typischen Attributkonstruktor. Dieser öffentliche Konstruktor nimmt einen Parameter und setzt eine Membervariable auf dessen Wert.

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

Sie können den Konstruktor überladen, um verschiedene Wertekombinationen zu berücksichtigen. Wenn Sie auch eine Eigenschaft für Ihre benutzerdefinierte Attributklasse definieren, können Sie beim Initialisieren des Attributs eine Kombination aus benannten und positionsbezogenen Parametern verwenden. In der Regel definieren Sie alle erforderlichen Parameter als Positionsparameter und alle optionalen Parameter als benannte. In diesem Fall kann das Attribut nicht ohne den erforderlichen Parameter initialisiert werden. Alle anderen Parameter sind optional.

Hinweis

In Visual Basic sollten Konstruktoren für eine Attributklasse kein Argument verwenden ParamArray .

Das folgende Codebeispiel zeigt, wie ein Attribut, das den vorherigen Konstruktor verwendet, mithilfe optionaler und erforderlicher Parameter angewendet werden kann. Es wird davon ausgegangen, dass das Attribut über einen erforderlichen booleschen Wert und eine optionale Zeichenfolgeneigenschaft verfügt.

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

Deklarieren von Eigenschaften

Wenn Sie einen benannten Parameter definieren oder eine einfache Möglichkeit zum Zurückgeben der von Ihrem Attribut gespeicherten Werte bereitstellen möchten, deklarieren Sie eine Eigenschaft. Attributeigenschaften sollten als öffentliche Entitäten mit einer Beschreibung des Datentyps deklariert werden, der zurückgegeben wird. Definieren Sie die Variable, die den Wert Ihrer Eigenschaft enthält, und ordnen Sie sie den get Und set Methoden zu. Im folgenden Codebeispiel wird veranschaulicht, wie eine Eigenschaft in Ihrem Attribut implementiert wird:

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

Beispiel für benutzerdefiniertes Attribut

Dieser Abschnitt enthält die vorherigen Informationen und zeigt, wie Sie ein Attribut entwerfen, das Informationen zum Autor eines Codeabschnitts dokumentiert. Das Attribut in diesem Beispiel speichert den Namen und die Ebene des Programmierers und ob der Code überprüft wurde. Es verwendet drei private Variablen, um die tatsächlichen Zu speichernden Werte zu speichern. Jede Variable wird durch eine öffentliche Eigenschaft dargestellt, die die Werte abruft und festlegt. Schließlich wird der Konstruktor mit zwei erforderlichen Parametern definiert:

[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

Sie können dieses Attribut mit dem vollständigen Namen oder dem abgekürzten Namen DeveloperAttributeDeveloperauf eine der folgenden Arten anwenden:

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

-or-

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

-or-

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

Das erste Beispiel zeigt das Attribut, das nur mit den erforderlichen benannten Parametern angewendet wird. Das zweite Beispiel zeigt das Attribut, das sowohl mit den erforderlichen als auch mit optionalen Parametern angewendet wird.

Siehe auch