Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
L’expression nameof produit une constante de chaîne qui correspond au nom dans la source pour presque n’importe quelle construction F# dans la source.
Syntaxe
nameof symbol
nameof<'TGeneric>
Remarques
nameof fonctionne en résolvant le symbole passé à celui-ci et produit le nom de ce symbole tel qu’il est déclaré dans votre code source. Cela est utile dans différents scénarios, tels que la journalisation et protège votre journalisation contre les modifications apportées au 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 "month" s’affiche dans le message d’erreur.
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)}"
nameof n’est pas une fonction de première classe et ne peut pas être utilisée comme tel. Cela signifie qu’elle ne peut pas être partiellement appliquée et que les valeurs ne peuvent pas être redirigées vers elle via des opérateurs de pipeline F#.
Nameof sur les opérateurs
Les opérateurs en F# peuvent être utilisés de deux manières, en tant que texte d’opérateur lui-même ou symbole représentant le formulaire compilé.
nameof sur un opérateur produit 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 que défini dans la source, et non le nom du type substitué sur un site d’appel.
La raison pour laquelle la syntaxe est différente est de s’aligner avec d’autres opérateurs intrinsèques F# comme typeof<> et typedefof<>. Cela rend F# cohérent avec les opérateurs qui agissent sur les types génériques et tout autre élément dans la source.
Nomof dans la correspondance de modèle
Le nameof modèle vous permet d’utiliser nameof dans une expression de correspondance de modèle. Cela est particulièrement utile lors de la mise en correspondance de valeurs de chaîne par rapport aux noms de symboles dans votre code, ce qui fournit une sécurité au moment de la compilation et des mises à jour automatiques lorsque vous refactorisez.
Un exemple pratique consiste à désérialiser des événements ou des messages dans lesquels les valeurs de chaîne représentent des noms de type ou de casse :
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
L’utilisation nameof au lieu de littéraux de chaîne comme "OrderCreated" offre plusieurs avantages :
- Si vous renommez un cas d’union discriminatoire, le modèle est automatiquement mis à jour.
- Le compilateur empêche les fautes de frappe en s’assurant que le symbole existe.
- Votre code reste cohérent pendant la refactorisation.
Vous pouvez également utiliser nameof avec des paramètres :
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# requiert une instance pour extraire le nom d’un membre d’instance avec nameof. Si une instance n’est pas facilement disponible, on peut être obtenu à l’aide Unchecked.defaultofde .
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