F#将通用参数约束为枚举类型

时间:2017-11-19 21:25:42

标签: generics f#

我正在尝试创建一种将Option<TEnum>转换为Nullable<int>的通用方法:

let toNullableInt (value : Option<'T>) =
   if value.IsSome then Nullable(int value.Value) else Nullable()

编译器推断这是Option<int> -> Nullable<int>

是否可以向'T添加约束,以便我可以将其用于枚举?

1 个答案:

答案 0 :(得分:2)

这是可能的(种类):

let toNullableInt (v : Option<'T> when 'T:> Enum) =
    if v.IsSome then Nullable(v.Value |> unbox |> int) else Nullable()

并快速检查确认确实:

type MyVals = 
| MyVal = 1000

MyVals.MyVal |> Option<MyVals>.Some |> toNullableInt
> 
val it : Nullable<int> = 1000

Option<MyVals>.None |> toNullableInt
> 
val it : Nullable<int> = null

不幸的是,这种方法无论如何都没有解决枚举类型的实例可能具有未在枚举中定义的值的问题,下面的表达式通过正确地强制转换一些外来int

enum</s><MyVals>10 |> Option<MyVals>.Some |> toNullableInt
> 
val it : Nullable<int> = 10

虽然您可能希望获得null而不是......

<强>更新 该问题的作者发现自己如何适应“未定义”枚举值的检查,我只是在下面的评论中重现最终解决方案以获得更好的可见性:

let toNullableInt (v : Option<'T> when 'T:> Enum) =
    match v with
   | Some x when Enum.IsDefined (typeof<'T>, x) -> 
        Nullable(LanguagePrimitives.EnumToValue(x))
   | _ -> Nullable ()

给定的早期检查带有“外来”枚举值输入现在可以根据需要运行:

enum<MyVals>10 |> Option<MyVals>.Some |> toNullableInt
>
val it : Nullable<int> = null