首页 > 解决方案 > 使用 Flags 属性将整数转换为枚举类型

问题描述

我有一个带有 flags 属性的枚举类型:

[<Flags>]
type StatusWord =
    | DATAPROCESS       = 0b0000000001
    | ERRORPRESENT      = 0b0000000010
    | CHECKSUMERROR     = 0b0000000100
    | PACKETSIZEERROR   = 0b0000001000
    | TIMEOUT           = 0b0000010000
    | DONOTRETRY        = 0b1000000000

在一些数据初始化期间,我有一个uint16要转换为枚举类型的值StatusWord,所以我可以比较它的属性:

let value: uint16 = 0b1000001001us
let flags: StatusWord = StatusWord value

但是,正如您可能猜到的那样,这段代码无法编译;转换不可用。同样,我也不能做明确的演员,例如。value :> StatusWordvalue :?> StatusWord。这是 C# 中的一项简单任务,因此我无法弄清楚为什么我不能在 F# 中执行此操作。

标签: enumscastingf#type-conversionflags

解决方案


因此,您必须担心两件事。一个(我认为您已经意识到)是您的基础枚举类型是 int32,而您的值是 uint16,因此需要在某处进行转换。二,你必须构造枚举类型。

StatusWord 看起来像一个构造函数(类似于 union case 成员),但它不是。因此,这里有两种使用 uint16 值的方法,第三种方法可以更好地提高可读性,如果你可以这样做的话。

let value = 0b1000001001us

// use F# enum operator
let flags1 = enum<StatusWord> (int value)

// use static Enum class
let flags2 = Enum.Parse(typeof<StatusWord>, string value) :?> StatusWord

// do bitwise stuff, of course now the compiler knows what you're doing
let flags3 = StatusWord.DATAPROCESS ||| StatusWord.PACKETSIZEERROR ||| StatusWord.DONOTRETRY

因为有多种方法,我不得不刷新我的记忆,我在

https://fsharpforfunandprofit.com/posts/enum-types/

强烈推荐阅读(该文章和该博客的其余部分 - 有多少人学习 F#)。


推荐阅读