C# 为什么要使用标志+;比特面具而不是一系列的布尔人?
如果我有一个对象可能处于一个或多个真/假状态,我总是有点不明白为什么程序员经常使用标志+位掩码,而不仅仅是使用几个布尔值 它遍布.NET框架。不确定这是否是最好的示例,但.NET framework具有以下特点:C# 为什么要使用标志+;比特面具而不是一系列的布尔人?,c#,enums,flags,C#,Enums,Flags,如果我有一个对象可能处于一个或多个真/假状态,我总是有点不明白为什么程序员经常使用标志+位掩码,而不仅仅是使用几个布尔值 它遍布.NET框架。不确定这是否是最好的示例,但.NET framework具有以下特点: public enum AnchorStyles { None = 0, Top = 1, Bottom = 2, Left = 4, Right = 8 } 因此,给定锚定样式,我们可以使用位掩码来确定选择了哪些状态。但是,似乎您可以通过为每
public enum AnchorStyles
{
None = 0,
Top = 1,
Bottom = 2,
Left = 4,
Right = 8
}
因此,给定锚定样式,我们可以使用位掩码来确定选择了哪些状态。但是,似乎您可以通过为每个可能的值定义bool属性的AnchorStyle类/结构或单个枚举值的数组来完成同样的事情
当然,我提出这个问题的主要原因是我想知道我是否应该在自己的代码中遵循类似的实践
那么,为什么要使用这种方法呢
- 更少的内存消耗?(它似乎不会消耗少于一个布尔数组/布尔结构)
- 比结构或数组更好的堆栈/堆性能
- 更快的比较操作?更快的增值/增值
- 对编写它的开发人员来说更方便
if ((flags & AnchorStyles.Top) == AnchorStyles.Top)
{
//Do stuff
}
- 以任意顺序轻松设置多个标志
- 易于保存,并将0101011系列数据保存到数据库中
但是,即使这样,我也不认为这是真正的原因。我之所以喜欢这些,是因为C#赋予我处理这些枚举的能力。我可以用一个表达式添加多个值。我也可以移除它们。我甚至可以使用enum使用单个表达式一次比较多个值。有了布尔值,代码可以变得,比方说,更加冗长。这是传统上减少内存使用的一种方式。所以,是的,它在C中已经过时了 作为一种编程技术,它在今天的系统中可能已经过时,您可以使用一系列布尔值,但是 比较存储为位掩码的值很快。使用AND或逻辑运算符并比较结果2整数 它使用的内存要少得多。将所有4个示例值放入位掩码将使用半个字节。使用bool数组时,很可能会对数组对象使用几个字节,对每个bool使用一个长单词。如果您必须存储一百万个值,您将确切地看到为什么位掩码版本更优越 它更易于管理,只需处理单个整数值,而布尔数组在数据库中的存储方式则截然不同
而且,由于内存布局,在各个方面都比阵列快得多。它几乎和使用单个32位整数一样快。我们都知道,这是数据操作的最快速度。它还可以使方法更清晰。想象一个10个布尔与1个位掩码的方法。我建议永远不要使用枚举标志,除非您正在处理一些非常严重的内存限制(不太可能)。您应该始终编写为维护而优化的代码 拥有多个布尔属性可以更容易地阅读和理解代码、更改值和提供Intellisense注释,更不用说降低bug的可能性了。如有必要,您可以始终在内部使用enum标志字段,只需确保使用布尔属性公开值的设置/获取。Raymond Chen有 当然,位域可以节省数据内存,但是 你必须使它与环境保持平衡 代码大小、可调试性和 减少了多线程
正如其他人所说,它的时代基本上已经过去了。仍然这样做很有诱惑力,因为小摆弄既有趣又酷,但它不再高效,它在维护方面存在严重缺陷,不能很好地处理数据库,除非你在嵌入式世界中工作,否则你有足够的内存。从域模型的角度来看,它只是在某些情况下更好地模拟现实。如果您有三个布尔值,如AccountIsInDefault和IsPreferredCustomer以及RequiresAlessTaxState,那么将它们添加到单个标记修饰枚举是没有意义的,因为它们不是同一域模型元素的三个不同值 但是如果你有一组布尔值,比如:
[Flags] enum AccountStatus {AccountIsInDefault=1,
AccountOverdue=2 and AccountFrozen=4}
或
然后,能够将帐户(或货物)的总状态存储在一个变量中是很有用的。。。表示一个域元素,其值可以表示任何可能的状态组合
[Flags] enum CargoState {ExceedsWeightLimit=1,
ContainsDangerousCargo=2, IsFlammableCargo=4,
ContainsRadioactive=8}