从歧视联盟映射到枚举

时间:2015-06-25 18:04:47

标签: enums f# discriminated-union

目前,我试图通过制作一个由C#GUI层和F#业务层组成的应用程序来自学一些F#。在GUI层中,用户在某些时候必须通过选择作为简单枚举的一部分的值来做出选择,例如,选择以下任一项:

enum {One, Two, Three}

我写了一个函数将枚举值转换为F#辨别联合

type MyValues = 
  | One
  | Two
  | Three

现在我必须翻译回来,并且已经厌倦了样板代码。有没有通用的方法将我的歧视联盟翻译成相应的枚举,反之亦然?

干杯,

2 个答案:

答案 0 :(得分:6)

You can also define the enum in F# and avoid doing conversions altogether:

type MyValues = 
  | One = 0
  | Two = 1
  | Three = 2

The = <num> bit tells the F# compiler that it should compile the type as a union. When using the type from C#, this will appear as a completely normal enum. The only danger is that someone from C# can call your code with (MyValues)4, which will compile, but it will cause incomplete pattern match exception if you are using match in F#.

答案 1 :(得分:1)

Here are generic DU/enum converters. 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 It maps the DU tag to the enum underlying value.