Namn på
Uttrycket nameof
skapar en strängkonstant som matchar namnet i källan för nästan alla F#-konstruktioner i källan.
Syntax
nameof symbol
nameof<'TGeneric>
Kommentarer
nameof
fungerar genom att matcha symbolen som skickas till den och skapar namnet på symbolen som den deklareras i källkoden. Detta är användbart i olika scenarier, till exempel loggning, och skyddar din loggning mot ändringar i källkoden.
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)
Den sista raden genererar ett undantag och "month"
visas i felmeddelandet.
Du kan ta ett namn på nästan alla F#-konstruktioner:
module M =
let f x = nameof x
printfn $"{(M.f 12)}"
printfn $"{(nameof M)}"
printfn $"{(nameof M.f)}"
nameof
är inte en förstklassig funktion och kan inte användas som sådan. Det innebär att den inte kan tillämpas delvis och att värden inte kan skickas till den via F#-pipelineoperatorer.
Namn på operatorer
Operatorer i F# kan användas på två sätt, som själva operatortexten eller en symbol som representerar det kompilerade formuläret. nameof
på en operator kommer att producera namnet på operatorn som den deklareras i källan. Om du vill hämta det kompilerade namnet använder du det kompilerade namnet i källan:
nameof(+) // "+"
nameof op_Addition // "op_Addition"
Namn på generiska
Du kan också ta ett namn på en allmän typparameter, men syntaxen är annorlunda:
let f<'a> () = nameof<'a>
f() // "a"
nameof<'TGeneric>
kommer att ta namnet på symbolen enligt definitionen i källan, inte namnet på den typ som ersätts på en samtalswebbplats.
Anledningen till att syntaxen är annorlunda är att anpassa till andra F#-inbyggda operatorer som typeof<>
och typedefof<>
. Detta gör F# konsekvent med avseende på operatorer som agerar på generiska typer och allt annat i källan.
Namn på i mönstermatchning
Med nameof
mönstret kan du använda nameof
i ett mönstermatchningsuttryck så här:
let f (str: string) =
match str with
| nameof str -> "It's 'str'!"
| _ -> "It is not 'str'!"
f "str" // matches
f "asdf" // does not match
Namn på med instansmedlemmar
F# kräver en instans för att extrahera namnet på en instansmedlem med nameof
. Om en instans inte är lätt tillgänglig kan du hämta en med hjälp av 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