特性 (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,此处使用缩写形式。 第一个实参是位置形参,第二个实参是属性。

特性是一种 .NET 编程构造,它使称为“特性”的对象能够与类型或其他程序元素关联。 特性所应用于的程序元素称为“特性目标”。 特性通常包含有关其目标的元数据。 在此上下文中,元数据可以为有关类型的任何数据(类型的字段和成员除外)。

F# 中的特性可应用于以下编程构造:函数、方法、程序集、模块、类型(类、记录、结构、接口、委托、枚举、联合等)、构造函数、属性、字段、参数、类型参数以及返回值。 不允许在类、表达式或工作流表达式内部的 let 绑定上使用特性。

通常,特性声明直接出现在特性目标的声明前面。 多个特性声明可以一起使用,如下所示。

[<Owner("Jason Carlson")>]
[<Company("Microsoft")>]
type SomeType1 =

可以在运行时使用 .NET 反射来查询特性。

您可以按前面的代码示例中的方式分别声明多个特性,或者,如果使用分号来分隔单个特性和构造函数,则可以在一组方括号中声明这些特性,如下所示。

[<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 指示特性支持使用程序集作为目标,则编译器会将特性应用于程序集。 大多数特性都不会同时应用于函数和程序集,但如果出现这种情况,则会将特性应用于程序的主函数。 如果显式指定了特性目标,则会将特性应用于指定的目标。

下表中显示了特性中 target 的有效值以及用法示例,尽管您通常不需要显式指定特性目标。

特性目标

示例

assembly

[<assembly: AssemblyVersionAttribute("1.0.0.0")>]

return

let function1 x : [<return: Obsolete>] int = x + 1

字段

[<field: DefaultValue>] val mutable x: int

属性

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

请参见

其他资源

F# 语言参考