我的对象Item
有几个可以组合的二进制状态
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
我需要将当前的值组合存储到一个变量中。原因是我需要将此值存储在数据库中。在 C++ 中,我会创建一个位掩码,其中一个状态占用一些位。.NET 中的好习惯吗?
我的对象Item
有几个可以组合的二进制状态
bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;
我需要将当前的值组合存储到一个变量中。原因是我需要将此值存储在数据库中。在 C++ 中,我会创建一个位掩码,其中一个状态占用一些位。.NET 中的好习惯吗?
您可以使用带有Flags
属性的枚举:
[Flags]
enum MyStates {
CanBeSold = 1,
CanBeBought = 2,
CanBeExchanged = 4
}
由于枚举是下面的整体数据类型,因此您可以以通常的方式组合它们:
state = MyStates.CanBeSold | MyStates.CanBeExchanged
请注意,这只适用于枚举值是 2 的幂(正如Doug Ferguson在评论中指出的那样),因此它们可以轻松组合并且在设置多个值时不会重叠。
您还可以将值定义为多个其他值的组合:
CanBeSoldOrBought = CanBeSold | CanBeBought
或者
CanBeSoldOrBought = 3
然后也可以按预期工作。例如,可以看到文件权限,其中 ReadWrite 通常是读取和写入位的组合。
是的,这是很常见的做法。框架本身也在几个地方使用它。
检查是否设置了特定位的常用方法是
if ((state & MyStates.CanBeSold) != 0) { ... }
创建一个枚举,其中值对应于整数中的位。添加 Flags 属性使您能够对枚举值执行更多位操作。
[Flags]
public enum CanBe {
Sold = 1,
Bought = 2,
Exchanged = 4
}
现在您可以在值之间使用 or 运算符:
CanBe can = CabBe.Sold | CanBe.Exchanged.
您可以使用 |= 运算符添加状态:
can |= CanBe.Sold;
或几种状态:
can |= CanBe.Sold | CanBe.Bought;
您可以使用 &= 运算符保持状态:
can &= CanBe.Sold;
或几种状态:
can &= CanBe.Sold | CanBe.Bought;
您可以使用 ~ 运算符来删除状态,以创建一个值的补码:
can &= ~CabBe.Bough;
或几种状态:
can &= ~(CabBe.Bough | CanBe.Exchanged);
您可以使用 & 运算符检查状态:
if ((can & CanBe.Sold) != 0) ...
或者一次有几个状态:
if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...
或者检查几个状态都设置好了:
if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...
您也可以在 .NET 中使用位掩码来做到这一点。
在您的枚举中,您可以将您的状态定义为值
public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }
然后在你的对象内,你可以做
if (item.State ^ ItemState.CanBeSold) ....
您可以使用指定每个位的标志枚举
[Flags]
enum MyStates {
CanBeSold = 0x1,
CanBeBought = 0x2,
CanBeExchanged = 0x4,
}
MyStates m_Flags;
// to set a flag:
m_Flags |= MyStates.CanBeSold;
// to unset a flag:
m_Flags &= ~MyStates.CanBeSold;