Deseo obtener el equivalente a Enum.GetName
para un miembro de la unión discriminado F #. Llamar al ToString()
me da TypeName + MemberName, que no es exactamente lo que quiero. Podría subscribirlo, por supuesto, pero ¿es seguro? ¿O tal vez hay una mejor manera?¿Cuál es el equivalente Enum.GetName para el miembro de la unión F #?
Respuesta
Es necesario utilizar las clases en el Microsoft.FSharp.Reflection
espacio de nombres por lo que: (¿y rápido debido a la falta de reflexión de uno de los métodos)
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"|]
Vine aquí por la sintaxis '' 'GetUnionFields''', gracias por eso. Mientras estoy aquí, pensé que señalaría que '' 'GetUnionCaseName''' podría escribirse de manera más sucinta como: ' '' let GetUnionCaseName (e: 'a) = (FSharpValue.GetUnionFields (e, typeof) <'a>) |> fst) .Name''' – philsquared
Tenga en cuenta que este es un enfoque muy lento. Definitivamente, desea almacenar en caché los resultados para obtener un rendimiento de kilometraje de este –
@ obras respuesta de DanielAsher, pero para que sea más elegante , me gustaría hacerlo de esta manera: (. Inspirado por this y 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
me gustaría proponer algo aún más concisa:
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
Cuando caso la unión es simple, GetName()
podrá someter el mismo que ToString()
:
> let tea = Tea
val tea : Beverage = Tea
> tea.GetName()
val it : string = "Tea"
> tea.ToString()
val it : string = "Tea"
Sin embargo, si el caso unión es más elegante, no habrá una diferencia:.
> 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. ¿Cuál es el uso de un objeto de unión constante?
- 2. ¿Cuál es el equivalente Android de/dev/video0 para tableta?
- 3. ¿Cuál es el equivalente en F # de la palabra clave predeterminada de C#?
- 4. ¿Cuál es el equivalente Ruby de "pythonic"?
- 5. ¿Cuál es la mejor manera de documentar el código f #?
- 6. ¿Cuál es el equivalente de argv [0]?
- 7. ¿Cuál es el equivalente de C# de un amigo?
- 8. Impresión F # unión discriminada
- 9. ¿Cuál es la contraparte de Scala de la Unión Discriminada en F #?
- 10. ¿Cuál es el equivalente Python de Tomcat?
- 11. ¿Cuál es el equivalente Monotouch de dealloc?
- 12. ¿Cuál es el equivalente de Ruby para StringReader de Java?
- 13. ¿Cuál es el equivalente de Varchar (máximo) para DB2?
- 14. ¿Cuál es el equivalente de java.sql.Types para MySQL TEXT?
- 15. ¿Cuál es el equivalente de write_attribute para asociaciones en Rails?
- 16. Cuál es el equivalente de PostgreSQL para ISNULL()
- 17. ¿Cuál es el equivalente de WPF para FlowLayoutPanel?
- 18. ¿Cuál es el equivalente de LINQ-a-SQL para Silverlight?
- 19. ¿Cuál es el equivalente de ObjectContext.ApplyCurrentValues para DbContext
- 20. ¿Cuál es el equivalente de Cloud-Init para Windows?
- 21. ¿Cuál es el equivalente de C++ para AutoResetEvent en Linux?
- 22. ¿Cuál es el equivalente de `cpp -dD` para clang?
- 23. ¿Cuál es el equivalente de la preg_quote de PHP?
- 24. ¿Cuál es el equivalente a + = en Matlab?
- 25. ¿Cuál es el equivalente Response.Redirect en Silverlight?
- 26. ¿Cuál es el C# equivalente a la instancia de Java()?
- 27. ¿Cuál es la semántica de una función miembro miembro?
- 28. ¿Cuál es la sintaxis para forzar el uso de un índice para una unión en MySQL?
- 29. Unión probada para miembro actual en uso
- 30. ¿Cuál es el equivalente Clojure más conciso para Ruby's Dir.glob()?
¡Cuidado! La misma expresión, x.ToString(), en diferentes ejecuciones de programas a veces me dan AssemblyName + TypeName y algunas veces AssemblyName + TypeName + MemberName. Otra expresión idéntica en el mismo tipo en cualquier otro lugar siempre me dará AssemblyName + TypeName + MemberName. Mismo problema con x.GetType(). Nombre. La respuesta aceptada es buena. –