Atributos (F#)

Os atributos permitem que os metadados sejam aplicados a uma construção de programação.

Sintaxe

[<target:attribute-name(arguments)>]

Comentários

Na sintaxe anterior, o destino é opcional e, se presente, especifica o tipo de entidade de programa ao qual o atributo se aplica. Os valores válidos para target são mostrados na tabela que aparece mais adiante neste documento.

O attribute-name refere-se ao nome (possivelmente qualificado com namespaces) de um tipo de atributo válido, com ou sem o sufixo Attribute que normalmente é usado em nomes de tipo de atributo. Por exemplo, o tipo ObsoleteAttribute pode ser encurtado para apenas Obsolete neste contexto.

Os argumentos são os argumentos para o construtor para o tipo de atributo. Se um atributo tiver um construtor sem parâmetros, a lista de argumentos e os parênteses poderão ser omitidos. Os atributos dão suporte a argumentos posicionais e argumentos nomeados. Argumentos posicionais são argumentos usados na ordem em que aparecem. Argumentos nomeados poderão ser usados se o atributo tiver propriedades públicas. Você pode defini-los usando a sintaxe a seguir na lista de argumentos.

property-name = property-value

Essas inicializações de propriedade podem estar em qualquer ordem, mas devem seguir qualquer argumento posicional. Veja a seguir um exemplo de um atributo que usa argumentos posicionais e inicializações de propriedade:

open System.Runtime.InteropServices

[<DllImport("kernel32", SetLastError=true)>]
extern bool CloseHandle(nativeint handle)

Neste exemplo, o atributo é DllImportAttribute, aqui usado de forma abreviada. O primeiro argumento é um parâmetro posicional e o segundo é uma propriedade.

Atributos são uma construção de programação .NET que permite que um objeto conhecido como atributo seja associado a um tipo ou outro elemento de programa. O elemento do programa ao qual um atributo é aplicado é conhecido como destino do atributo. O atributo geralmente contém metadados sobre seu destino. Nesse contexto, metadados podem ser quaisquer dados sobre o tipo que não sejam seus campos e membros.

Atributos em F# podem ser aplicados às seguintes construções de programação: funções, métodos, assemblies, módulos, tipos (classes, registros, estruturas, interfaces, delegados, enumerações, uniões e assim por diante), construtores, propriedades, campos, parâmetros, parâmetros de tipo e valores retornados. Atributos não são permitidos em ligações let dentro de classes, expressões ou expressões de fluxo de trabalho.

Normalmente, a declaração do atributo aparece diretamente antes da declaração do destino do atributo. Múltiplas declarações de atributo podem ser usadas juntas, da seguinte maneira:

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

Você pode consultar atributos em tempo de execução usando reflexão .NET.

Você pode declarar múltiplos atributos individualmente, como no exemplo de código anterior, ou pode declará-los em um conjunto de colchetes se usar um ponto e vírgula para separar os atributos e construtores individuais, da seguinte maneira:

[<Owner("Darren Parker"); Company("Microsoft")>]
type SomeType2 =

Os atributos normalmente encontrados incluem o atributo Obsolete, atributos para considerações de segurança, atributos para suporte a COM, atributos relacionados à propriedade do código e atributos que indicam se um tipo pode ser serializado. O exemplo a seguir demonstra o uso do atributo 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

Para os destinos de atributo assembly e module, você aplica os atributos a uma associação do de nível superior em seu assembly. Você pode incluir a palavra assembly ou ``module`` na declaração do atributo, da seguinte maneira:

open System.Reflection
[<assembly:AssemblyVersionAttribute("1.0.0.0")>]
[<``module``:MyCustomModuleAttribute>]
do
   printfn "Executing..."

Se você omitir o destino do atributo para um atributo aplicado a uma associação do, o compilador do F# tentará determinar o destino do atributo que faz sentido para esse atributo. Muitas classes de atributo têm um atributo do tipo System.AttributeUsageAttribute que inclui informações sobre os possíveis destinos suportados para esse atributo. Se o atributo System.AttributeUsageAttribute indicar que o atributo dá suporte a funções como destinos, o atributo será usado para ser aplicado ao ponto de entrada principal do programa. Se o atributo System.AttributeUsageAttribute indicar que o atributo dá suporte a assemblies como destinos, o compilador usará o atributo a ser aplicado ao assembly. A maioria dos atributos não se aplica a funções e assemblies, mas nos casos em que isso ocorre, o atributo é aplicado à função principal do programa. Se o destino do atributo for especificado explicitamente, o atributo será aplicado ao destino especificado.

Embora você normalmente não precise especificar explicitamente o destino do atributo, os valores válidos para destino em um atributo junto com exemplos de uso são mostrados na tabela a seguir:

Destino do atributo Exemplo
assembly
[<assembly: AssemblyVersion("1.0.0.0")>]
module
[<``module``: MyCustomAttributeThatWorksOnModules>]
return
let function1 x : [<return: MyCustomAttributeThatWorksOnReturns>] int = x + 1
field
[<DefaultValue>] val mutable x: int
propriedade
[<Obsolete>] this.MyProperty = x
param
member this.MyMethod([<Out>] x : ref<int>) = x := 10
type
[<type: StructLayout(LayoutKind.Sequential)>]
type MyStruct =
  struct
    val x : byte
    val y : int
  end

Confira também