Nameof
L'espressione nameof
produce una costante stringa che corrisponde al nome nell'origine per quasi qualsiasi costrutto F# nell'origine.
Sintassi
nameof symbol
nameof<'TGeneric>
Osservazioni:
nameof
funziona risolvendo il simbolo passato e produce il nome di tale simbolo come dichiarato nel codice sorgente. Ciò è utile in vari scenari, ad esempio la registrazione e protegge la registrazione dalle modifiche apportate al codice sorgente.
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)
L'ultima riga genererà un'eccezione e "month"
verrà visualizzata nel messaggio di errore.
È possibile prendere il nome di quasi ogni costrutto F#:
module M =
let f x = nameof x
printfn $"{(M.f 12)}"
printfn $"{(nameof M)}"
printfn $"{(nameof M.f)}"
nameof
non è una funzione di prima classe e non può essere usata come tale. Ciò significa che non può essere applicato parzialmente e i valori non possono essere inviati tramite pipe tramite operatori della pipeline F#.
Nameof sugli operatori
Gli operatori in F# possono essere usati in due modi, come testo dell'operatore stesso o un simbolo che rappresenta il modulo compilato. nameof
in un operatore produrrà il nome dell'operatore come dichiarato nell'origine. Per ottenere il nome compilato, usare il nome compilato nell'origine:
nameof(+) // "+"
nameof op_Addition // "op_Addition"
Nameof nei generics
È anche possibile accettare un nome di un parametro di tipo generico, ma la sintassi è diversa:
let f<'a> () = nameof<'a>
f() // "a"
nameof<'TGeneric>
accetta il nome del simbolo come definito nell'origine, non il nome del tipo sostituito in un sito di chiamata.
Il motivo per cui la sintassi è diversa consiste nell'allineare gli altri operatori intrinseci F# come typeof<>
e typedefof<>
. Ciò rende F# coerente rispetto agli operatori che agiscono su tipi generici e qualsiasi altro elemento nell'origine.
Nameof nei criteri di ricerca
Il nameof
modello consente di usare nameof
in un'espressione di corrispondenza dei criteri di ricerca come illustrato di seguito:
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 con membri dell'istanza
F# richiede un'istanza di per estrarre il nome di un membro dell'istanza con nameof
. Se un'istanza non è facilmente disponibile, è possibile ottenere un'istanza usando 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