Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A nameof expressão produz uma constante de cadeia de caracteres que corresponde ao nome na origem de quase qualquer construção F# na origem.
Sintaxe
nameof symbol
nameof<'TGeneric>
Observações
nameof funciona resolvendo o símbolo passado para ele e produz o nome desse símbolo conforme ele é declarado em seu código-fonte. Isso é útil em vários cenários, como registro em log, e protege o registro em log contra alterações no código-fonte.
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)
A última linha gerará uma exceção e "month" será mostrada na mensagem de erro.
Você pode usar um nome de quase todos os constructos F#:
module M =
let f x = nameof x
printfn $"{(M.f 12)}"
printfn $"{(nameof M)}"
printfn $"{(nameof M.f)}"
nameof não é uma função de primeira classe e não pode ser usada como tal. Isso significa que não pode ser parcialmente aplicado e os valores não podem ser canalizados para ele por meio de operadores de pipeline F#.
Nameof em operadores
Os operadores em F# podem ser usados de duas maneiras, como um próprio texto de operador ou um símbolo que representa o formulário compilado.
nameof em um operador produzirá o nome do operador como ele é declarado na origem. Para obter o nome compilado, use o nome compilado na origem:
nameof(+) // "+"
nameof op_Addition // "op_Addition"
Nameof em genéricos
Você também pode usar um nome de um parâmetro de tipo genérico, mas a sintaxe é diferente:
let f<'a> () = nameof<'a>
f() // "a"
nameof<'TGeneric> assumirá o nome do símbolo conforme definido na origem, não o nome do tipo substituído em um site de chamada.
O motivo pelo qual a sintaxe é diferente é se alinhar com outros operadores intrínsecos F# como typeof<> e typedefof<>. Isso torna o F# consistente com relação aos operadores que atuam em tipos genéricos e qualquer outra coisa na origem.
Nameof na correspondência de padrões
O nameof padrão permite que você use nameof em uma expressão de correspondência de padrão. Isso é particularmente útil ao corresponder valores de cadeia de caracteres com os nomes dos símbolos em seu código, fornecendo segurança em tempo de compilação e atualizações automáticas ao refatorar.
Um exemplo prático é desserializar eventos ou mensagens em que valores de cadeia de caracteres representam nomes de tipo ou caso:
type EventType =
| OrderCreated
| OrderShipped
| OrderDelivered
let handleEvent eventName data =
match eventName with
| nameof OrderCreated -> printfn "Processing order creation: %s" data
| nameof OrderShipped -> printfn "Processing order shipment: %s" data
| nameof OrderDelivered -> printfn "Processing order delivery: %s" data
| _ -> printfn "Unknown event type: %s" eventName
handleEvent "OrderCreated" "Order #123" // matches first case
O uso nameof em vez de literais de cadeia de caracteres como "OrderCreated" oferece vários benefícios:
- Se você renomear um caso de união discriminado, o padrão será atualizado automaticamente.
- O compilador impede erros de digitação, garantindo que o símbolo exista.
- Seu código permanece consistente durante a refatoração.
Você também pode usar nameof com parâmetros:
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 com membros da instância
F# requer uma instância para extrair o nome de um membro de instância com nameof. Se uma instância não estiver disponível facilmente, uma poderá ser obtida 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