测试是否在数值中设置一个标志一种简便方式是执行按位

时间:2022-04-28 04:24:44

枚举Enum 全称(Enumeration),即一种由一组称为枚举数列表的定名常量构成的奇特类型。可以看出枚举的呈现时为了使我们可以在措施中便利的使用一些特定值的常量,一般的使用大家都对照熟悉,本文主要介绍枚举的特性 FlagAttribute。

FlagAttribute是什么?

Flag 特性微软的解释是:指示可以将枚举作为位域(即一组标识表记标帜)措置惩罚惩罚,FlagsAttribute属性就是枚举类型的一项可选属性,它的主要感化是可以将枚举作为位域措置惩罚惩罚(P.S. C#不撑持位域)。所谓位域是单个存储单元内相邻二进制位的调集。通过为枚举添加这个属性,可以转变枚举的一些行为来满足我们的需要。

好比我们有如下枚举的界说:

public enum OrderTypeEnum { Init, Complete, Waiting, Paid }

逻辑与操纵我相信大家都对照熟悉了,对付整数来说,| 操纵就是将其转化为二进制再进行或运算。OrderTypeEnum.Init | OrderTypeEnum.Complete做的事情实际上是 0001 | 0010 = 0011 = 3再转换成(OrderTypeEnum)3就是OrderTypeEnum.Paid了.

如果我们对两个枚举值做 | 操纵,那功效会是什么样呢?

OrderTypeEnum result = OrderTypeEnum.Waiting | OrderTypeEnum.Paid;

凭据或操纵的道理:0010 | 0011 = 0011(3) Paid ,本色上我们想要的功效是想讲两个枚举值都作为或操纵的功效,但是因为枚举值默认是从0开始按序递增的,那么颠末或操纵之后就得不到我们想要的功效,那怎么办呢,这时候就需要 给枚举加上 [Flags] 的Attribute,我们先来看一下FlagsAttribute界说的准则:

使用FlagsAttribute枚举才是对数字值执行按位运算 (AND、 OR 独有或) 的自界说属性。

在 2 的幂,即 1、 2、 4、 8 等中界说枚举常量。 这意味着不重叠中组合的枚举常量的各个标识表记标帜。

请考虑创建针对常用的标识表记标帜组合的枚举的常数。 例如,如果你有用于文件 I/O 操纵的枚举包罗枚举的常数Read = 1和Write = 2,请考虑创建枚举的常数ReadWrite = Read OR Write,它结合Read和Write标识表记标帜。 别的,可用于组合标识表记标帜的按位 OR 操纵视为在某些情况下,不应为用于简单任务所需的一个高级的观点。

如果为标识表记标帜枚举常量中界说为负数,因为很多标识表记标帜位置可能会设置为 1,这可能会使你的代码的混乱,并鼓励编码错误,请务必小心。

测试是否在数值中设置一个标识表记标帜一种简便方法是执行按位,操纵之间的数字值和标识表记标帜枚举的常数,它将所有位都设置为不同错误应于标识表记标帜的零的数字值中,然后测试该操纵的功效是否即是该标识表记标帜枚举常量。

使用None用作枚举其值为零的常量的标识表记标帜名称。 不能使用None按位运算中,来测试一个标识表记标帜,因为功效始终为零的枚举的常数。 但是,你可以执行的逻辑不之间的数字值的按位、 对照和None枚举的常量,以确定是否已设置在数值中的任何位。

如果你创建而不是标识表记标帜枚举的值枚举,它是仍须要创建None枚举的常数。 原因是,默认情况下用于枚举的内存初始化为零的大众语言运行时。 因此,如果不决义其值为零的常量,枚举将包罗在创建时犯警值。

如果你的应用措施需要暗示明显默认情况下,请考虑使用其值为零暗示默认值的枚举的常数。 如果没有任何默认情况下,请考虑使用其值为零的枚举的常数意味着不由任何其他枚举常量暗示这种情况。

不决义一个枚举值,只是为了镜像与枚举自己的状态。 例如,不界说仅用于枚举的结束符号的枚举的常数。 如果你需要确定在枚举的最后一个值,请显式查抄该值。 别的,你可以执行范畴查抄第一个和最后一个枚举常量,如果范畴内的所有值都是有效。

不要指定保存供将来使用的枚举的常数。

当你界说的要领或属性,它给与作为值的枚举的常数时,请考虑验证值。 原因是,即使该数值不在枚举中界说,你可以强制转换为枚举类型的数字值。

我们看到第二句报告我们当加了Flags的特性之后默认的枚举值就会以2的幂一次递增,好比 20,21,22,23(1,2,,4,8....)

那我们从头看一下从头界说之后的或操纵会是什么功效呢?

[Flags] public enum OrderTypeEnum { Init, Complete, Waiting, Paid }  

此时我们再来看:OrderTypeEnum result = OrderTypeEnum.Complete | OrderTypeEnum.Waiting | OrderTypeEnum.Paid ;

0010 | 0100 | 1000 = 1110 我们可以看到本色上就是做了二进制的或运算,将所有位值做了合并

当我们可以用做位运算的时候,就不只仅是或,与,非,异或等操纵都可以实现。

我们知道通过这样可以把枚举值合并 OrderTypeEnum result = OrderTypeEnum.Complete | OrderTypeEnum.Waiting | OrderTypeEnum.Paid ;

那么同理也可以来判断这样的调集中是否包罗某个枚举值:

result.HasFlag(OrderTypeEnum.Paid)  

写在最后

枚举通过添加Flags的特性使得它能够拥有位运算的能力,更便利了我们再日常代码中的使用。