从受歧视联合映射到枚举
Map from discriminated union to enum
目前,我正在尝试通过制作一个由 C# GUI 层和 F# 业务层组成的应用程序来自学一些 F#。在 GUI 层中,用户有时必须通过选择作为简单枚举一部分的值来做出选择,例如选择以下任一项:
enum {One, Two, Three}
我编写了一个函数来将枚举值转换为 F# 可区分联合
type MyValues =
| One
| Two
| Three
现在我不得不翻译回来,我已经厌倦了样板代码。有没有一种通用的方法可以将我的可区分联合转换为相应的枚举,反之亦然?
干杯,
您还可以在 F# 中定义枚举并完全避免进行转换:
type MyValues =
| One = 0
| Two = 1
| Three = 2
= <num>
位告诉 F# 编译器它应该将类型编译为联合。当使用 C# 中的类型时,这将显示为完全正常的枚举。唯一的危险是来自 C# 的人可以用 (MyValues)4
调用你的代码,这将编译,但如果你在 F# 中使用 match
,它会导致不完整的模式匹配异常。
这里是通用 DU/enum 转换器。
open Microsoft.FSharp.Reflection
type Union<'U>() =
static member val Cases =
FSharpType.GetUnionCases(typeof<'U>)
|> Array.sortBy (fun case -> case.Tag)
|> Array.map (fun case -> FSharpValue.MakeUnion(case, [||]) :?> 'U)
let ofEnum e =
let i = LanguagePrimitives.EnumToValue e
Union.Cases.[i - 1]
let toEnum u =
let i = Union.Cases |> Array.findIndex ((=) u)
LanguagePrimitives.EnumOfValue (i + 1)
let du : MyValues = ofEnum ConsoleColor.DarkGreen
let enum : ConsoleColor = toEnum Three
它将 DU 标记映射到枚举基础值。
目前,我正在尝试通过制作一个由 C# GUI 层和 F# 业务层组成的应用程序来自学一些 F#。在 GUI 层中,用户有时必须通过选择作为简单枚举一部分的值来做出选择,例如选择以下任一项:
enum {One, Two, Three}
我编写了一个函数来将枚举值转换为 F# 可区分联合
type MyValues =
| One
| Two
| Three
现在我不得不翻译回来,我已经厌倦了样板代码。有没有一种通用的方法可以将我的可区分联合转换为相应的枚举,反之亦然?
干杯,
您还可以在 F# 中定义枚举并完全避免进行转换:
type MyValues =
| One = 0
| Two = 1
| Three = 2
= <num>
位告诉 F# 编译器它应该将类型编译为联合。当使用 C# 中的类型时,这将显示为完全正常的枚举。唯一的危险是来自 C# 的人可以用 (MyValues)4
调用你的代码,这将编译,但如果你在 F# 中使用 match
,它会导致不完整的模式匹配异常。
这里是通用 DU/enum 转换器。
open Microsoft.FSharp.Reflection
type Union<'U>() =
static member val Cases =
FSharpType.GetUnionCases(typeof<'U>)
|> Array.sortBy (fun case -> case.Tag)
|> Array.map (fun case -> FSharpValue.MakeUnion(case, [||]) :?> 'U)
let ofEnum e =
let i = LanguagePrimitives.EnumToValue e
Union.Cases.[i - 1]
let toEnum u =
let i = Union.Cases |> Array.findIndex ((=) u)
LanguagePrimitives.EnumOfValue (i + 1)
let du : MyValues = ofEnum ConsoleColor.DarkGreen
let enum : ConsoleColor = toEnum Three
它将 DU 标记映射到枚举基础值。