Nameof

L’expression nameof produit une constante de chaîne qui correspond au nom dans la source pour presque toutes les constructions F# dans la source.

Syntaxe

nameof symbol
nameof<'TGeneric>

Notes

L’expression nameof résout le symbole qui lui a été passé et produit le nom de ce symbole tel qu’il est déclaré dans votre code source. Cela s’avère utile dans différents scénarios, tels que la journalisation et permet de protéger votre journalisation contre les changements au niveau du code source.

let months =
    [
        "January"; "February"; "March"; "April";
        "May"; "June"; "July"; "August"; "September";
        "October"; "November"; "December"
    ]

let lookupMonth month =
    if (month > 12 || month < 1) then
        invalidArg (nameof month) ($"Value passed in was %d{month}.")

    months[month-1]

printfn "%s" (lookupMonth 12)
printfn "%s" (lookupMonth 1)
printfn "%s" (lookupMonth 13)

La dernière ligne lève une exception et le message d’erreur affiche "month".

Vous pouvez prendre le nom de presque chaque construction F# :

module M =
    let f x = nameof x

printfn $"{(M.f 12)}"
printfn $"{(nameof M)}"
printfn $"{(nameof M.f)}"

L’expression nameof n’est pas une fonction de première classe et ne peut pas être utilisée en tant que telle. Cela signifie qu’elle ne peut pas être appliquée partiellement et que les valeurs ne peuvent pas être dirigées vers l’expression via des opérateurs pipeline F#.

Nameof sur les opérateurs

Les opérateurs en F# peuvent être utilisés de deux manières : comme un texte d’opérateur ou un symbole représentant la forme compilée. nameof sur un opérateur génère le nom de l’opérateur tel qu’il est déclaré dans la source. Pour obtenir le nom compilé, utilisez le nom compilé dans la source :

nameof(+) // "+"
nameof op_Addition // "op_Addition"

Nameof sur les génériques

Vous pouvez également prendre le nom d’un paramètre de type générique, mais la syntaxe est différente :

let f<'a> () = nameof<'a>
f() // "a"

nameof<'TGeneric> prend le nom du symbole tel qu’il est défini dans la source, et non le nom du type remplacé sur un site d’appel.

La syntaxe est différente afin de permettre l’alignement sur d’autres opérateurs intrinsèques F# tels que typeof<> et typedefof<>. Ainsi, F# est cohérent en ce qui concerne les opérateurs qui agissent sur les types génériques et tout autre élément dans la source.

Nameof dans les critères spéciaux

Le modèle nameof vous permet d’utiliser nameof dans une expression de critères spéciaux, comme suit :

let f (str: string) =
    match str with
    | nameof str -> "It's 'str'!"
    | _ -> "It is not 'str'!"

f "str" // matches
f "asdf" // does not match

Nameof avec les membres d’instance

F# nécessite une instance pour extraire le nom d’un membre d’instance avec nameof. Si une instance n’est pas immédiatement disponible, vous pouvez en obtenir une à l’aide de Unchecked.defaultof.

type MyRecord = { MyField: int }
type MyClass() =
    member _.MyProperty = ()
    member _.MyMethod () = ()

nameof Unchecked.defaultof<MyRecord>.MyField   // MyField
nameof Unchecked.defaultof<MyClass>.MyProperty // MyProperty
nameof Unchecked.defaultof<MyClass>.MyMethod   // MyMethod