F# 中的严格通用枚举转换

Strict generic enum conversion in F#

我想编写一个签名为 int -> 'TEnum 的函数,它会在目标枚举不包含输入值的情况下抛出异常。这是我的第一次尝试:

let parseEnum<'TEnum when 'TEnum : enum<int>> (value : int) : 'TEnum =
    let enumType = typeof<'TEnum>
    if not <| Enum.IsDefined (enumType, value) then
        raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)

    enum value

编译器向我显示以下错误消息:"error FS0001: The declared type parameter 'TEnum' cannot be used here since the type parameter cannot be resolved at compile time"(我认为这是因为 enum 函数具有额外的约束)。

嗯,那好吧,我明白问题所在了。我将使用 statically resolved type parameter。这是我的第二次尝试:

let inline parseEnum2 (value : int) : ^TEnum =
    let enumType = typeof<^TEnum>
    if not <| Enum.IsDefined (enumType, value) then
        raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)

    enum value

但编译器仍然抱怨:"error FS3156: Unexpected token '>' or incomplete expression" 在行 typeof<^TEnum>

我做错了什么?这个函数怎么写?

您只需要在 'hat' 符号 ˆ< 之间添加一个 space,如下所示:

let enumType = typeof< ^TEnum>

其实你不需要帽子,你可以这样写:

open System
let inline parseEnum2 value : 'TEnum =
    let enumType = typeof<'TEnum>
    if not <| Enum.IsDefined (enumType, value) then
        raise <| ArgumentException (sprintf "Invalid value of %A: %d" enumType value)

    enum value

因为在这种情况下静态约束是自动推断的,所以真正需要编写 'hat' 的唯一地方是手动编写静态约束。