属性 (F#)
属性を使用すると、プログラミング構成要素にメタデータを適用できます。
[<target:attribute-name(arguments)>]
解説
前の構文では、target は省略可能です。省略されていない場合は、属性が適用されるプログラム要素の種類を指定します。 target の有効な値は、このドキュメントの後半の表に示されています。
attribute-name は、有効な属性型の名前 (名前空間で修飾される場合があります) を示しますが、通常は属性型の名前に使用されるサフィックス Attribute が付く場合と付かない場合があります。 たとえば、このコンテキストでは、ObsoleteAttribute 型を Obsolete に短縮できます。
arguments は、属性型のコンストラクターへの引数です。 属性に既定のコンストラクターがある場合は、引数リストとかっこを省略できます。 属性は、位置指定引数と名前付き引数の両方をサポートします。 位置指定引数は、並べられた順序で使用される引数です。 名前付き引数は、属性がパブリック プロパティを持つ場合に使用できます。 これらを設定するには、引数リストで次の構文を使用します。
property-name = property-value
このようなプロパティの初期化は、任意の順序で実行できますが、位置指定引数に従う必要があります。 位置指定引数とプロパティの初期化を使用する属性の例を次に示します。
open System.Runtime.InteropServices
[<DllImport("kernel32", SetLastError=true)>]
extern bool CloseHandle(nativeint handle)
この例では、属性である DllImportAttribute を短縮形で使用しています。 最初の引数は位置指定パラメーターで、2 番目の引数はプロパティです。
属性は .NET プログラミング構成要素の 1 つで、これにより、属性と呼ばれるオブジェクトを、型または他のプログラム要素に関連付けることができます。 属性が適用されるプログラム要素を、属性ターゲットと呼びます。 通常、属性には、ターゲットに関するメタデータが含まれます。 このコンテキストでは、メタデータが、型に関する任意のデータ (フィールドおよびメンバーを除く) である可能性があります。
F# の属性は、関数、メソッド、アセンブリ、モジュール、型 (クラス、レコード、構造体、インターフェイス、デリゲート、列挙型、共用体など)、コンストラクター、プロパティ、フィールド、パラメーター、型パラメーター、および戻り値の各プログラミング構成要素に適用できます。 属性は、クラス、式、またはワークフロー式の内部の let バインディングでは使用できません。
通常、属性宣言は、属性ターゲットの宣言の直前にあります。 次のように、複数の属性宣言をまとめて使用できます。
[<Owner("Jason Carlson")>]
[<Company("Microsoft")>]
type SomeType1 =
.NET リフレクションを使用すると、属性を実行時に問い合わせることができます。
前のコード例のように、複数の属性を個別に宣言するか、または、次に示すように、セミコロンを使用して個別の属性およびコンストラクターを区切る場合は、それらの属性を 1 組の角かっこ内で宣言できます。
[<Owner("Darren Parker"); Company("Microsoft")>]
type SomeType2 =
よく使用される属性には、Obsolete 属性、セキュリティ上の理由で使用される属性、COM サポート用の属性、コードの所有権に関する属性、および型をシリアル化できるかどうかを示す属性があります。 Obsolete 属性の使用例を次に示します。
open System
[<Obsolete("Do not use. Use newFunction instead.")>]
let obsoleteFunction x y =
x + y
let newFunction x y =
x + 2 * y
// The use of the obsolete function produces a warning.
let result1 = obsoleteFunction 10 100
let result2 = newFunction 10 100
属性ターゲット assembly および module については、アセンブリ内の最上位の do バインディングに属性を適用します。 次のように、属性宣言に assembly または module という単語を含めることができます。
open System.Reflection
[<assembly:AssemblyVersionAttribute("1.0.0.0")>]
do
printfn "Executing..."
do バインディングに適用される属性の属性ターゲットを省略した場合、F# コンパイラは、その属性に適した属性ターゲットの判断を試みます。 多くの属性クラスには、その属性に対してサポートされるターゲットに関する情報を含んだ、AttributeUsageAttribute 型の属性があります。 AttributeUsageAttribute が、属性がターゲットとして関数をサポートすることを示している場合、その属性はプログラムのメイン エントリ ポイントに適用されます。 AttributeUsageAttribute が、属性がターゲットとしてアセンブリをサポートすることを示している場合、コンパイラはその属性をアセンブリに適用します。 ほとんどの属性は関数とアセンブリのいずれかにのみ適用されますが、両方に適用される属性の場合は、プログラムの main 関数に適用されます。 属性ターゲットを明示的に指定した場合は、指定したターゲットに属性が適用されます。
通常は属性ターゲットを明示的に指定する必要はありませんが、属性内の target の有効値を、使用例と共に次の表に示します。
属性ターゲット |
例 |
---|---|
assembly |
[<assembly: AssemblyVersionAttribute("1.0.0.0")>] |
return |
let function1 x : [<return: Obsolete>] int = x + 1 |
field |
[<field: DefaultValue>] val mutable x: int |
property |
[<property: Obsolete>] this.MyProperty = x |
param |
member this.MyMethod([<param: Out>] x : ref<int>) = x := 10 |
type |
[<type: StructLayout(Sequential)>] type MyStruct = struct x : byte y : int end |