Verfassen von benutzerdefinierten Attributen

Zum Entwerfen eigener benutzerdefinierter Attribute müssen Sie keine neuen Verfahren erlernen. Wenn Sie mit dem objektorientierten Programmieren vertraut sind und Klassen entwerfen können, verfügen Sie bereits über die wichtigsten Kenntnisse. Benutzerdefinierte Attribute sind im Prinzip herkömmliche Klassen, die direkt oder indirekt von System.Attribute abgeleitet werden. Wie herkömmliche Klassen enthalten benutzerdefinierte Attribute Methoden zum Speichern und Abrufen von Daten.

Dies sind die ersten Schritte zum ordnungsgemäßen Entwerfen benutzerdefinierter Attributklassen:

  • Anwenden von AttributeUsageAttribute

  • Deklarieren der Attributklasse

  • Deklarieren von Konstruktoren

  • Deklarieren von Eigenschaften

Dieser Abschnitt beschreibt die einzelnen Schritte und endet mit einem Beispiel für ein benutzerdefiniertes Attribut.

Anwenden von AttributeUsageAttribute

Die Deklaration eines benutzerdefinierten Attributs beginnt mit AttributeUsageAttribute. Hiermit werden einige der wichtigsten Eigenschaften der Attributklasse definiert. Sie können z. B. angeben, ob das Attribut von anderen Klassen geerbt und auf welche Elemente das Attribut angewendet werden kann. Im folgenden Codefragment wird die Verwendung von AttributeUsageAttribute dargestellt.

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
<AttributeUsage(AttributeTargets.All, Inherited := False, AllowMultiple := true)>

Die System.AttributeUsageAttribute-Klasse verfügt über drei Member, die für das Erstellen benutzerdefinierter Attribute wichtig sind: AttributeTargets, Inherited und AllowMultiple.

AttributeTargets-Member

Im vorherigen Beispiel wurde AttributeTargets.Allfestgelegt. Dies gibt an, dass das Attribut auf alle Programmelemente angewendet werden kann. Sie können auch AttributeTargets.Class festlegen und damit angeben, dass das Attribut nur auf eine Klasse angewendet werden kann, oder AttributeTargets.Method, um anzugeben, dass das Attribut nur auf eine Methode angewendet werden kann. So können alle Programmelemente durch ein benutzerdefiniertes Attribut für die Beschreibung gekennzeichnet werden.

Sie können auch mehrere Instanzen von AttributeTargets übergeben. Im folgenden Codefragment wird angegeben, dass ein benutzerdefiniertes Attribut auf beliebige Klassen bzw. Methoden angewendet werden kann.

[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage (AttributeTargets.Class Or AttributeTargets.Method)>

Inherited-Eigenschaft

Die Inherited-Eigenschaft gibt an, ob das Attribut von Klassen geerbt werden kann, die von den Klassen abgeleitet wurden, auf die das Attribut angewendet wird. Diese Eigenschaft benötigt entweder das Flag true (Standardeinstellung) oder das Flag false. Im folgenden Beispiel hat MyAttribute z. B. den als Standard festgelegten Inherited-Wert true, während YourAttribute den Inherited-Wert false hat.

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

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

Dann werden beide Attribute auf eine Methode in der Basisklasse MyClass angewendet.

public class MyClass
{
    [MyAttribute]
    [YourAttribute]
    public virtual void MyMethod() 
    {
        //...
    }
}
' In Microsoft Visual Basic, you apply multiple attributes
' by separating them with commas.
Public Class [MyClass]
    <MyAttribute, YourAttribute> Public Overridable Sub MyMethod()
        '...
    End Sub
End Class

Schließlich wird die Klasse YourClass von der Basisklasse MyClass geerbt. Die Methode MyMethod zeigt MyAttribute, jedoch nicht YourAttribute.

public class YourClass: MyClass
{
      //MyMethod will have MyAttribute but not YourAttribute.
      public override void MyMethod()
      {
         //...
      }

}
Public Class YourClass
   Inherits [MyClass]
      'MyMethod will have MyAttribute but not YourAttribute.
      Public overrides Sub MyMethod()
         '...
      End Sub
End Class

AllowMultiple-Eigenschaft

Die AllowMultiple-Eigenschaft gibt an, ob mehrere Instanzen eines Attributs für ein Element vorhanden sein können. Wenn sie auf true festgelegt ist, sind mehrere Instanzen zulässig. Wenn sie auf false (Standardeinstellung) festgelegt ist, ist nur eine Instanz zulässig.

Im folgenden Codebeispiel hat MyAttribute den als Standard festgelegten AllowMultiple-Wert false, während YourAttribute den Wert true hat.

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

[AttributeUsage(AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
'This defaults to AllowMultiple = false.
<AttributeUsage(AttributeTargets.Method)> 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 veranschaulicht 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(){
    //...
    }
}
' In Microsoft Visual Basic you apply multiple attributes
' by separating them with commas.
Public Class [MyClass]
    'This produces an error.
    'Duplicates are not allowed.
    <MyAttribute, MyAttribute> Public Overridable Sub MyMethod()
        '...
    End Sub

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

Wenn sowohl für die AllowMultiple-Eigenschaft als auch für die Inherited-Eigenschaft true festgelegt ist, kann eine von einer anderen Klasse geerbte Klasse ein Attribut erben und die Anwendung einer anderen Instanz desselben Attributs in derselben untergeordneten Klasse zulassen. Wenn AllowMultiple auf false festgelegt ist, werden die Werte der Attribute in der übergeordneten Klasse durch beliebige neue Instanzen desselben Attributs in der untergeordneten Klasse überschrieben.

Deklarieren der Attributklasse

Nach dem Anwenden von AttributeUsageAttribute können Sie beginnen, die spezifischen Merkmale des Attributs zu definieren. Die Deklaration einer Attributklasse ähnelt der Deklaration einer herkömmlichen Klasse, wie das folgende Codebeispiel veranschaulicht.

public class MyAttribute : System.Attribute 
{
    // . . . 
}
' This attribute is only usable with methods
<AttributeUsage(AttributeTargets.Method)> Public Class MyAttribute
    Inherits System.Attribute
    ' . . . 
End Class

Mit dieser Attributdefinition werden die folgenden Punkte veranschaulicht:

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

  • Die Konvention besagt, dass der Name der Attributklasse mit dem Word Attribute endet . Auch wenn diese Konvention keine Vorschrift darstellt, so dient sie doch der besseren Lesbarkeit. Beim Anwenden des Attributs ist das Einschließen des Wortes "Attribute" freigestellt.

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

  • In Microsoft Visual Basic müssen alle benutzerdefinierten Attributklassen über das AttributeUsageAttribute-Attribut verfügen.

Deklarieren von Konstruktoren

Attribute werden genau wie herkömmliche Klassen mit Konstruktoren initialisiert. Im folgenden Codefragment wird ein typischer Konstruktor eines Attributs dargestellt. Dieser öffentliche Konstruktor akzeptiert einen Parameter und legt dessen Wert auf den einer Membervariablen fest.

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

Sie können den Konstruktor überladen, um verschiedene Kombinationen von Werten zu ermöglichen. Wenn Sie außerdem eine Eigenschaft für die benutzerdefinierte Attributklasse definieren, können Sie beim Initialisieren des Attributs eine Kombination benannter und positionaler Parameter verwenden. Normalerweise definieren Sie alle erforderlichen Parameter als positional und alle optionalen Parameter als benannt. In diesem Fall kann das Attribut nicht ohne den erforderlichen Parameter initialisiert werden. Alle übrigen Parameter sind optional. Beachten Sie, dass Konstruktoren für ein Attribut in Visual Basic kein ParamArray-Argument verwenden sollten.

Das folgende Codebeispiel veranschaulicht die Anwendung eines Attributs, das den vorherigen Konstruktor verwendet, mit optionalen und erforderlichen Parametern. Dabei wird vorausgesetzt, dass das Attribut über einen erforderlichen booleschen Wert und eine optionale Zeichenfolgeeigenschaft verfügt.

//One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
//One required (positional) parameter is applied.
[MyAttribute(false)]
'One required (positional) and one optional (named) parameter are applied.
<MyAttribute(False, OptionalParameter := "optional data")>
' ...
'One required (positional) parameter is applied.
<MyAttribute(False)>

Deklarieren von Eigenschaften

Wenn Sie einen benannten Parameter definieren oder das Zurückgeben der vom Attribut gespeicherten Werte erleichtern möchten, deklarieren Sie eine Eigenschaft. Attributeigenschaften müssen als öffentliche Einheiten mit einer Beschreibung des zurückgegebenen Datentyps deklariert werden. Definieren Sie die Variable, die den Wert der Eigenschaft enthält, und ordnen Sie sie der Get-Methode und der Set-Methode zu. Das folgende Codebeispiel veranschaulicht die Implementierung einer einfachen Eigenschaft im 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

Beispiel für ein benutzerdefiniertes Attribut

In diesem Abschnitt werden die zuvor behandelten Informationen zusammengefasst. Es wird der Entwurf eines einfachen Attributs erläutert, das Informationen über den Autor eines Codeabschnitts dokumentiert. Das Attribut in diesem Beispiel speichert Namen und Qualifikation des Programmierers und gibt an, ob der Code überprüft wurde. Dabei werden drei private Variablen zum Aufnehmen der Werte verwendet, die gespeichert werden sollen. 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 : System.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 System.Attribute
    
    'Private fields.
    Private m_name As String
    Private m_level As String
    Private m_reviewed As Boolean    
    
    'This constructor defines two required parameters: name and level.
    Public Sub New(name As String, level As String)
        Me.m_name = name
        Me.m_level = level
        Me.m_reviewed = False
    End Sub
    
    'Define Name property.
    'This is a read-only attribute.    
    Public Overridable ReadOnly Property Name() As String
        Get
            Return m_name
        End Get
    End Property 
    
    'Define Level property.
    'This is a read-only attribute.    
    Public Overridable ReadOnly Property Level() As String
        Get
            Return m_level
        End Get
    End Property
    
    'Define Reviewed property. 
    'This is a read/write attribute.    
    Public Overridable Property Reviewed() As Boolean
        Get
            Return m_reviewed
        End Get
        Set
            m_reviewed = value
        End Set
    End Property
End Class

Sie können dieses Attribut, wie folgt, unter Verwendung des vollständigen Namens DeveloperAttribute oder des abgekürzten Namens Developer anwenden.

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

Im ersten Beispiel wird die Anwendung des Attributs nur mit den erforderlichen benannten Parametern dargestellt, während im zweiten Beispiel die Anwendung des Attributs mit den erforderlichen und optionalen Parametern erläutert wird.

Siehe auch

Referenz

System.Attribute
AttributeUsageAttribute Class

Weitere Ressourcen

Erweitern von Metadaten mithilfe von Attributen