Desidero ottenere l'equivalente di Enum.GetName
per un membro del sindacato discriminato F #. Chiamare ToString()
mi dà TypeName + MemberName, che non è esattamente quello che voglio. Potrei sottostrarla, ovviamente, ma è sicuro? O forse c'è un modo migliore?Qual è l'equivalente Enum.GetName per il membro del sindacato F #?
risposta
È necessario utilizzare le classi nel Microsoft.FSharp.Reflection
namespace così: (? E veloce a causa della mancanza di riflessione per uno dei metodi)
open Microsoft.FSharp.Reflection
///Returns the case name of the object with union type 'ty.
let GetUnionCaseName (x:'a) =
match FSharpValue.GetUnionFields(x, typeof<'a>) with
| case, _ -> case.Name
///Returns the case names of union type 'ty.
let GetUnionCaseNames <'ty>() =
FSharpType.GetUnionCases(typeof<'ty>) |> Array.map (fun info -> info.Name)
// Example
type Beverage =
| Coffee
| Tea
let t = Tea
> val t : Beverage = Tea
GetUnionCaseName(t)
> val it : string = "Tea"
GetUnionCaseNames<Beverage>()
> val it : string array = [|"Coffee"; "Tea"|]
Sono venuto qui per la sintassi '' 'GetUnionFields''' - grazie per questo. Mentre sono qui ho pensato di far notare che '' 'GetUnionCaseName''' potrebbe essere scritto in modo un po 'più succinto come: ' '' lascia GetUnionCaseName (e:' a) = (FSharpValue.GetUnionFields (e, typeof <'a>) |> fst) .Name''' – philsquared
Si noti che questo è un approccio molto lento, si vorrebbe sicuramente memorizzare nella cache i risultati al fine di ottenere un certo milleo di prestazioni da questo –
@ opere risposta di DanielAsher, ma per renderlo più elegante , lo farei in questo modo: (. Ispirato this e this)
type Beverage =
| Coffee
| Tea
static member ToStrings() =
Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof<Beverage>)
|> Array.map (fun info -> info.Name)
override self.ToString() =
sprintf "%A" self
Vorrei proporre qualcosa di ancora più conciso:
open Microsoft.FSharp.Reflection
type Coffee = { Country: string; Intensity: int }
type Beverage =
| Tea
| Coffee of Coffee
member x.GetName() =
match FSharpValue.GetUnionFields(x, x.GetType()) with
| (case, _) -> case.Name
Quando caso l'unione è semplice, GetName()
può portare lo stesso di ToString()
:
> let tea = Tea
val tea : Beverage = Tea
> tea.GetName()
val it : string = "Tea"
> tea.ToString()
val it : string = "Tea"
Tuttavia, se caso unione è più elaborato, ci sarà una differenza:.
> let coffee = Coffee ({ Country = "Kenya"; Intensity = 42 })
val coffee : Beverage = Coffee {Country = "Kenya"; Intensity = 42;}
> coffee.GetName()
val it : string = "Coffee"
> coffee.ToString()
val it : string = "Coffee {Country = "Kenya"; Intensity = 42;}"
- 1. Assegnazione tra membri del sindacato
- 2. È legale inizializzare più campi sovrapposti nell'elenco di inizializzazione di un membro del sindacato?
- 3. Qual è il modo migliore per documentare il codice f #?
- 4. Cos'è un sindacato?
- 5. selezionare un membro del sindacato in base a un parametro del modello
- 6. Qual è lo scopo dell'annotazione del tipo flessibile in F #?
- 7. Come vengono memorizzati i membri del sindacato?
- 8. F # - Qual è la parola chiave "it"?
- 9. Qual è il motivo dell'utilizzo; in F # elenca invece di?
- 10. Qual è la sintassi F # per "non uguale a"?
- 11. qual è il membro della variante in C++?
- 12. Funzioni membro di chiamata F # nel costruttore
- 13. F # Query Espressione "Il campo, costruttore o membro" Contiene "non è definito"
- 14. Il membro sottoposto a override TypeScript non è il sottotipo del membro originale
- 15. Qual è il? genere?
- 16. Qual è il keyCode per "$"?
- 17. F # design pattern
- 18. Qual è l'uso della parola chiave "protetta" all'interno di un sindacato?
- 19. Generazione del codice F #
- 20. Qual è la differenza tra "1.0f" e "1.f"?
- 21. Qual è il modo standard per ottimizzare la ricorsione reciproca in F #/Scala?
- 22. inizializzare un array di sindacato dichiarazione
- 23. determinare se l'utente è membro del gruppo
- 24. Qual è il punto del tipo generico in foreach?
- 25. Qual è il vantaggio del contenitore Docker per un'istanza memcached?
- 26. rapido: qual è il modificatore del tipo forzato (!) Per
- 27. Qual è il nome del tasto "Fn" per Awesome wm?
- 28. Qual è il significato del reso per riferimento?
- 29. Qual è l'ordine del caricatore per il webpack?
- 30. Qual è il simbolo del metodo per + = in ruby?
Attenzione! La stessa stessa espressione, x.ToString(), a diverse esecuzioni del programma a volte mi dà AssemblyName + TypeName e talvolta AssemblyName + TypeName + MemberName. Un'altra espressione identica sullo stesso tipo altrove mi darà sempre AssemblyName + TypeName + MemberName. Lo stesso problema con x.GetType(). Nome. La risposta accettata è buona. –