Attributs (F#)
Les attributs permettent l'application de métadonnées à une construction de programmation.
[<target:attribute-name(arguments)>]
Notes
Dans la syntaxe précédente, target est facultatif ; s'il est présent, il spécifie le genre d'entité de programme auquel l'attribut s'applique. Les valeurs valides de target sont répertoriées dans le tableau figurant ci-après dans ce document.
attribute-name fait référence au nom (éventuellement qualifié avec des espaces de noms) d'un type d'attribut valide, avec ou sans le suffixe Attribute utilisé habituellement dans les noms de type d'attribut. Par exemple, le type ObsoleteAttribute peut être abrégé en Obsolete dans ce contexte.
arguments sont les arguments au constructeur pour le type d'attribut. Si un attribut possède un constructeur par défaut, la liste d'arguments et les parenthèses peuvent être omises. Les attributs prennent en charge les arguments positionnels et les arguments nommés. Les arguments positionnels sont des arguments utilisés dans l'ordre dans lequel ils apparaissent. Il est possible d'utiliser des arguments nommés si l'attribut possède des propriétés publiques. Vous pouvez les définir en utilisant la syntaxe suivante dans la liste d'arguments.
property-name = property-value
De telles initialisations de propriété peuvent être définies dans n'importe quel ordre, mais elles doivent suivre les arguments positionnels. L'exemple suivant illustre un attribut qui utilise des arguments positionnels et des initialisations de propriété.
open System.Runtime.InteropServices
[<DllImport("kernel32", SetLastError=true)>]
extern bool CloseHandle(nativeint handle)
Dans cet exemple, l'attribut est DllImportAttribute (utilisé ici sous forme abrégée). Le premier argument est un paramètre positionnel et le second est une propriété.
Les attributs sont une construction de programmation .NET qui permet à un objet appelé attribut d'être associé à un type ou à un autre élément de programme. L'élément de programme auquel un attribut est appliqué est appelé cible d'attribut. L'attribut contient généralement des métadonnées sur sa cible. Dans ce contexte, les métadonnées peuvent être des données quelconques sur le type, sauf ses champs et ses membres.
En F#, les attributs peuvent être appliqués aux constructions de programmation suivantes : fonctions, méthodes, assemblys, modules, types (classes, enregistrements, structures, interfaces, délégués, énumérations, unions, etc.), constructeurs, propriétés, champs, paramètres, paramètres de type et valeurs de retour. Les attributs ne sont pas autorisés sur les liaisons let dans des classes, des expressions ou des expressions de workflow.
En général, la déclaration attribute apparaît directement avant la déclaration de la cible d'attribut. Vous pouvez combiner plusieurs déclarations attribute, comme suit.
[<Owner("Jason Carlson")>]
[<Company("Microsoft")>]
type SomeType1 =
Vous pouvez interroger des attributs au moment de l'exécution à l'aide de la réflexion .NET.
Vous pouvez déclarer plusieurs attributs individuellement, comme dans l'exemple de code précédent, ou vous pouvez les déclarer dans une paire de crochets si vous utilisez un point-virgule pour séparer les attributs et les constructeurs individuels, comme indiqué ici.
[<Owner("Darren Parker"); Company("Microsoft")>]
type SomeType2 =
Parmi les attributs généralement rencontrés, citons l'attribut Obsolete, les attributs en matière de sécurité, les attributs pour la prise en charge COM, les attributs en rapport avec la propriété du code, et les attributs indiquant si un type peut être sérialisé. L'exemple suivant illustre l'utilisation de l'attribut 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
Pour les cibles d'attribut assembly et module, vous appliquez les attributs à la liaison do de niveau supérieur dans votre assembly. Vous pouvez inclure le mot assembly ou module dans la déclaration attribute, comme suit.
open System.Reflection
[<assembly:AssemblyVersionAttribute("1.0.0.0")>]
do
printfn "Executing..."
Si vous omettez la cible d'attribut pour un attribut appliqué à une liaison do, le compilateur F# tente de déterminer la cible d'attribut qui est appropriée pour cet attribut. De nombreuses classes d'attributs ont un attribut de type AttributeUsageAttribute qui inclut les informations à propos des cibles prises en charge pour cet attribut. Si AttributeUsageAttribute indique que l'attribut prend en charge des fonctions comme cibles, l'attribut est pris pour être appliqué au point d'entrée principal du programme. Si AttributeUsageAttribute indique que l'attribut prend en charge des assemblys comme cibles, le compilateur prend l'attribut pour l'appliquer à l'assembly. La plupart des attributs ne s'appliquent pas en même temps à des fonctions et à des assemblys, mais si c'est le cas, l'attribut est pris pour être appliqué à la fonction principale du programme. Si la cible d'attribut n'est pas spécifiée explicitement, l'attribut est appliqué à la cible spécifiée.
Bien qu'il soit généralement inutile de spécifier explicitement la cible d'attribut, les valeurs valides pour target dans un attribut sont répertoriées dans le tableau suivant, avec des exemples d'utilisation.
Cible d'attribut |
Exemple |
---|---|
assembly |
[<assembly: AssemblyVersionAttribute("1.0.0.0")>] |
return |
let function1 x : [<return: Obsolete>] int = x + 1 |
champ |
[<field: DefaultValue>] val mutable x: int |
Propriété |
[<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 |