カスタム属性を設計するには、多くの新しい概念を学習する必要はありません。 オブジェクト指向プログラミングに慣れているし、クラスを設計する方法を知っている場合は、既に必要な知識のほとんどがあります。 カスタム属性は、 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 つのメンバー (AttributeTargets、Inherited、AllowMultiple) があります。
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
ですが、 YourAttribute
の Inherited 値は 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
から継承されます。 メソッドMyMethod
MyAttribute
が表示されますが、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
に設定されている場合、別のクラスから継承されたクラスは属性を継承し、同じ子クラスに同じ属性の別のインスタンスを適用できます。
AllowMultipleが false
に設定されている場合、親クラス内の属性の値は、子クラス内の同じ属性の新しいインスタンスによって上書きされます。
属性クラスの宣言
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 番目の例は、必須パラメーターと省略可能なパラメーターの両方で適用される属性を示しています。
こちらも参照ください
.NET