为什么使用flags + bitmasks而不是一系列布尔?

Win*_*ett 24 c# enums flags

鉴于我有一个可能处于一个或多个真/假状态的对象的情况,我总是有点模糊为什么程序员经常使用标志+位掩码而不是仅仅使用几个布尔值.

它遍布.NET框架.不确定这是否是最好的示例,但.NET框架具有以下内容:

public enum AnchorStyles
{
    None = 0,
    Top = 1,
    Bottom = 2,
    Left = 4,
    Right = 8
}
Run Code Online (Sandbox Code Playgroud)

因此,给定锚样式,我们可以使用位掩码来确定选择哪个状态.但是,似乎您可以使用AnchorStyle类/结构来完成相同的操作,其中为每个可能的值或单个枚举值的数组定义了bool属性.

当然,我的问题的主要原因是我想知道我是否应该使用自己的代码进行类似的练习.

那么,为什么要用这种方法呢?

  • 减少内存消耗?(它似乎不会消耗少于bools的数组/结构)
  • 比结构或数组更好的堆栈/堆性能?
  • 更快的比较操作?更快的增值/删除?
  • 编写它的开发人员更方便吗?

gbj*_*anb 18

它传统上是一种减少内存使用的方法.所以,是的,它在C#中相当陈旧:--)

作为一种编程技术,它在今天的系统中可能已经过时了,你可以使用一系列bool,但是......

比较存储为位掩码的值很快.使用AND和OR逻辑运算符并比较生成的2个整数.

它使用相当少的内存.将所有4个示例值放在位掩码中将使用半个字节.使用bool数组,很可能会为数组对象使用几个字节,并为每个bool使用一个长字.如果你必须存储一百万个值,你就会明白为什么bitmask版本更优越.

它更容易管理,你只需要处理一个整数值,而一个bool数组将存储完全不同,比如数据库.

而且,由于内存布局,每个方面都比阵列快得多.它几乎与使用单个32位整数一样快.我们都知道,对于数据操作而言,速度最快.


Jan*_*oom 12

  • 轻松设置任何顺序的多个标志.

  • 易于保存并获得数据库的0101011系列.

  • 请注意,即使作为单独的列,SQL Server也会将这些列优化为单个字节:http://msdn.microsoft.com/en-us/library/ms177603.aspx (2认同)

Jhe*_*ico 7

除此之外,它更容易向位域添加新的位含义而不是向类添加新的布尔值.从一个实例到另一个实例,比一系列布尔值更容易复制位域.

  • @Winston:序列化格式发生变化,并且很难找到接受旧数据默认值的良好序列化器,并且旧版本不会丢弃未知字段。二进制接口发生变化,这可能会导致一系列所需的更新,并且需要对该结构的全面验证支持。(当然,*合约*必须明确声明“忽略未知位”或“未知位导致错误”)。此外,在实现层面上,将它们作为一个整体进行处理更容易。 (2认同)
  • @Winston如果你已经创建了API怎么办?然后,每个可能升级到新版本的人都必须更改代码,因为在方法中添加了新的bool.如果它是枚举,则必须在那里进行任何更改以保持相同的代码使用它.这就是为什么.NET框架更喜欢枚举而不是布尔值. (2认同)

Mic*_*tum 6

它还可以使方法更清晰.想象一个方法,10个bool对比1个Bitmask.