次の方法で共有


カスタム属性を記述する

カスタム属性を設計するには、多くの新しい概念を学習する必要はありません。 オブジェクト指向プログラミングに慣れているし、クラスを設計する方法を知っている場合は、既に必要な知識のほとんどがあります。 カスタム属性は、 System.Attribute クラスから直接または間接的に派生する従来のクラスです。 従来のクラスと同様に、カスタム属性にはデータを格納および取得するメソッドが含まれています。

カスタム属性クラスを適切に設計する主な手順は次のとおりです。

このセクションでは、これらの各手順について説明し、最後に カスタム属性の例を示します

AttributeUsageAttribute の適用

カスタム属性宣言は、属性クラスの主要な特性の一部を定義する System.AttributeUsageAttribute 属性で始まります。 たとえば、属性を他のクラスで継承できるかどうか、または属性を適用できる要素を指定できます。 次のコード フラグメントは、 AttributeUsageAttributeの使用方法を示しています。

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

AttributeUsageAttributeには、カスタム属性の作成に重要な 3 つのメンバー (AttributeTargetsInheritedAllowMultiple) があります。

AttributeTargets メンバー

前の例では、 AttributeTargets.All を指定し、この属性をすべてのプログラム要素に適用できることを示しています。 または、 AttributeTargets.Classを指定して、属性をクラスにのみ適用できることを示すか、 AttributeTargets.Method、属性をメソッドにのみ適用できることを示します。 すべてのプログラム要素は、この方法でカスタム属性によって説明用にマークできます。

複数の AttributeTargets 値を渡すこともできます。 次のコード フラグメントは、カスタム属性を任意のクラスまたはメソッドに適用できることを指定します。

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

継承されたプロパティ

AttributeUsageAttribute.Inherited プロパティは、属性が適用されるクラスから派生したクラスによって属性を継承できるかどうかを示します。 このプロパティは、 true (既定値) または false フラグを受け取ります。 次の例では、 MyAttribute の既定の Inherited 値は true ですが、 YourAttributeInherited 値は false です。

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

次に、基底クラスのメソッドに次の 2 つの属性が適用 MyClass

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

最後に、 YourClass クラスは基底クラスの MyClassから継承されます。 メソッドMyMethodMyAttributeが表示されますが、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 プロパティ

AttributeUsageAttribute.AllowMultiple プロパティは、属性の複数のインスタンスが要素に存在できるかどうかを示します。 trueに設定すると、複数のインスタンスが許可されます。 false (既定値) に設定すると、1 つのインスタンスのみが許可されます。

次の例では、 MyAttribute の既定の AllowMultiple 値は false ですが、 YourAttribute の値は 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

これらの属性の複数のインスタンスが適用されると、 MyAttribute コンパイラ エラーが発生します。 次のコード例は、 YourAttribute の有効な使用方法と、 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

AllowMultiple プロパティと Inherited プロパティの両方が true に設定されている場合、別のクラスから継承されたクラスは属性を継承し、同じ子クラスに同じ属性の別のインスタンスを適用できます。 AllowMultiplefalse に設定されている場合、親クラス内の属性の値は、子クラス内の同じ属性の新しいインスタンスによって上書きされます。

属性クラスの宣言

AttributeUsageAttributeを適用したら、属性の詳細の定義を開始します。 属性クラスの宣言は、次のコードで示すように、従来のクラスの宣言に似ています。

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

この属性定義は、次の点を示しています。

  • 属性クラスはパブリック クラスとして宣言する必要があります。

  • 慣例により、属性クラスの名前は Attribute という単語で終わります。 この規則は必須ではありませんが、読みやすくするために推奨されます。 属性を適用する場合、属性という単語を含めることは省略可能です。

  • すべての属性クラスは、 System.Attribute クラスから直接または間接的に継承する必要があります。

  • Microsoft Visual Basic では、すべてのカスタム属性クラスに System.AttributeUsageAttribute 属性が必要です。

コンストラクターの宣言

従来のクラスと同様に、属性はコンストラクターで初期化されます。 次のコード フラグメントは、一般的な属性コンストラクターを示しています。 このパブリック コンストラクターはパラメーターを受け取り、その値と等しいメンバー変数を設定します。

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

コンストラクターをオーバーロードして、さまざまな値の組み合わせに対応できます。 カスタム属性クラスの プロパティ も定義する場合は、属性の初期化時に名前付きパラメーターと位置指定パラメーターの組み合わせを使用できます。 通常、必要なすべてのパラメーターを位置指定パラメーターとして定義し、すべての省略可能なパラメーターを名前付きとして定義します。 この場合、必要なパラメーターがないと属性を初期化できません。 その他のパラメーターはすべて省略可能です。

Visual Basic では、属性クラスのコンストラクターでは、 ParamArray 引数を使用しないでください。

次のコード例は、省略可能なパラメーターと必須パラメーターを使用して、前のコンストラクターを使用する属性を適用する方法を示しています。 この属性には、1 つの必須のブール値と 1 つの省略可能な文字列プロパティがあることを前提としています。

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

プロパティの宣言

名前付きパラメーターを定義する場合、または属性によって格納されている値を簡単に返す方法を提供する場合は、プロパティを宣言 します。 属性プロパティは、返されるデータ型の説明を持つパブリック エンティティとして宣言する必要があります。 プロパティの値を保持する変数を定義し、 get メソッドおよび set メソッドに関連付けます。 次のコード例は、属性にプロパティを実装する方法を示しています。

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

カスタム属性の例

このセクションでは、前の情報を組み込み、コードセクションの作成者に関する情報を文書化する属性を設計する方法を示します。 この例の属性は、プログラマの名前とレベル、およびコードがレビューされたかどうかを格納します。 3 つのプライベート変数を使用して、保存する実際の値を格納します。 各変数は、値を取得および設定するパブリック プロパティによって表されます。 最後に、コンストラクターは 2 つの必須パラメーターで定義されます。

[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

この属性は、フル ネーム、 DeveloperAttribute、または省略名の Developerを使用して、次のいずれかの方法で適用できます。

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

-or-

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

-or-

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

最初の例では、必須の名前付きパラメーターのみを使用して適用される属性を示します。 2 番目の例は、必須パラメーターと省略可能なパラメーターの両方で適用される属性を示しています。

こちらも参照ください