Condividi tramite


Attributi (F#)

Gli attributi consentono l'applicazione dei metadati a un costrutto di programmazione.

Sintassi

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

Osservazioni

Nella sintassi precedente, il di destinazione è facoltativo e, se presente, specifica il tipo di entità di programma a cui si applica l'attributo. I valori validi per il di destinazione sono mostrati nella tabella che appare più avanti in questo documento.

Il nome dell'attributo si riferisce al nome (possibilmente qualificato con namespace) di un tipo di attributo valido, con o senza il suffisso Attribute solitamente usato nei nomi dei tipi di attributo. Ad esempio, il tipo ObsoleteAttribute può essere abbreviato in Obsolete in questo contesto.

Gli argomenti sono gli argomenti del costruttore per il tipo di attributo. Se un attributo ha un costruttore senza parametri, è possibile omettere l'elenco di argomenti e le parentesi. Gli attributi supportano sia argomenti posizionali che argomenti denominati. Gli argomenti posizionali sono argomenti utilizzati nell'ordine in cui appaiono. Gli argomenti denominati possono essere usati se l'attributo ha proprietà pubbliche. È possibile impostarli usando la sintassi seguente nell'elenco di argomenti.

property-name = property-value

Tali inizializzazioni di proprietà possono essere in qualsiasi ordine, ma devono seguire qualsiasi argomento posizionale. Di seguito è riportato un esempio di attributo che usa argomenti posizionali e inizializzazioni di proprietà:

open System.Runtime.InteropServices

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

In questo esempio, l'attributo è DllImportAttribute, usato qui in forma abbreviata. Il primo argomento è un parametro posizionale e il secondo è una proprietà.

Gli attributi sono un costrutto di programmazione .NET che consente a un oggetto noto come attributo di essere associato a un tipo o a un altro elemento di programma. L'elemento di programma a cui viene applicato un attributo è noto come target dell'attributo . L'attributo contiene in genere metadati relativi alla destinazione. In questo contesto, i metadati possono essere dati relativi al tipo, eccetto i suoi campi e membri.

Gli attributi in F# possono essere applicati ai costrutti di programmazione seguenti: funzioni, metodi, assembly, moduli, tipi (classi, record, strutture, interfacce, delegati, enumerazioni, unioni e così via), costruttori, proprietà, campi, parametri, parametri, parametri di tipo e valori restituiti. Gli attributi non sono consentiti nelle associazioni let all'interno di classi, espressioni o espressioni del flusso di lavoro.

In genere, la dichiarazione dell'attributo viene visualizzata direttamente prima della dichiarazione della destinazione dell'attributo. È possibile usare più dichiarazioni di attributi insieme, come indicato di seguito:

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

È possibile eseguire query sugli attributi in fase di esecuzione usando la reflection .NET.

È possibile dichiarare più attributi singolarmente, come nell'esempio di codice precedente, oppure dichiararli in un set di parentesi quadre se si usa un punto e virgola per separare i singoli attributi e costruttori, come indicato di seguito:

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

Gli attributi rilevati in genere includono l'attributo Obsolete, gli attributi per considerazioni sulla sicurezza, gli attributi per il supporto COM, gli attributi correlati alla proprietà del codice e gli attributi che indicano se un tipo può essere serializzato. Nell'esempio seguente viene illustrato l'uso dell'attributo 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

Per le destinazioni dell'attributo assembly e module, applica gli attributi a un'associazione do di primo livello nel tuo assembly. È possibile includere la parola assembly o ``module`` nella dichiarazione dell'attributo, come indicato di seguito:

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

Se si omette la destinazione dell'attributo per un attributo applicato a un'associazione do, il compilatore F# tenta di determinare la destinazione dell'attributo appropriata per tale attributo. Molte classi di attributi hanno un attributo di tipo System.AttributeUsageAttribute che include informazioni sulle possibili destinazioni supportate per tale attributo. Se il System.AttributeUsageAttribute indica che l'attributo supporta funzioni come destinazioni, l'attributo viene considerato valido per il punto di ingresso principale del programma. Se il System.AttributeUsageAttribute indica che l'attributo supporta gli assembly come destinazioni, il compilatore accetta l'attributo da applicare all'assembly. La maggior parte degli attributi non si applica sia alle funzioni che agli assembly, ma nei casi in cui lo fanno, l'attributo viene preso per applicare alla funzione principale del programma. Se la destinazione dell'attributo viene specificata in modo esplicito, l'attributo viene applicato alla destinazione specificata.

Anche se in genere non è necessario specificare in modo esplicito la destinazione dell'attributo, i valori validi per destinazione in un attributo insieme ad esempi di utilizzo sono illustrati nella tabella seguente:

Obiettivo attributo Esempio
Assemblea
[<assembly: AssemblyVersion("1.0.0.0")>]
modulo
[<``module``: MyCustomAttributeThatWorksOnModules>]
metodo
[<MyCustomAttributeThatWorksOnMethods>]
let someFunction() = 42
classe
[<MyCustomAttributeThatWorksOnClasses>]
type MyClass(myValue: int) =
    member _.MyValue = myValue
Struct
[<MyCustomAttributeThatWorksOnStructs>]
[<Struct>]
type MyStruct(myValue: int) =
    member _.MyValue = myValue
interfaccia
[<MyCustomAttributeThatWorksOnInterfaces>]
type MyInterface =
    abstract member Prop: string
enum
[<MyCustomAttributeThatWorksOnEnums>]
type Color =
    | Red = 0
    | Green = 1
    | Blue = 2
costruttore
type MyClass(myValue: int) =
    member _.MyValue = myValue

    [<MyCustomAttributeThatWorksOnCtors>]
    new () = MyClass 42
ritorno
let function1 x : [<return: MyCustomAttributeThatWorksOnReturns>] int = x + 1
campo
[<DefaultValue>] val mutable x: int
proprietà
[<Obsolete>] this.MyProperty = x
Parametro
member this.MyMethod([<Out>] x : ref<int>) = x := 10
digitare
[<type: StructLayout(LayoutKind.Sequential)>]
type MyStruct =
  struct
    val x : byte
    val y : int
  end

Vedere anche