Dela via


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