如何在一个变量中存储多个状态?

发布于 2024-08-13 20:35:41 字数 219 浏览 10 评论 0原文

我的对象 Item 有几种可以组合的二进制状态,

bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;

我需要将当前的值组合存储到一个变量中。原因 是我需要将这个值存储在数据库中。在 C++ 中,我将创建一个位掩码 其中一个状态占据一些位。这是 .NET 中的良好做法吗?

My object Item has several binary states which can be combined

bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;

I need to store current combination of values into one variable. The reason
is that I need to store this value in DB. In C++ I would create a bit-mask
where one state occupies some bit. Is it good practice in .NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

涙—继续流 2024-08-20 20:35:41

您可以使用带有 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) { ... }

You can use an enumeration with the Flags attribute:

[Flags]
enum MyStates {
  CanBeSold = 1,
  CanBeBought = 2,
  CanBeExchanged = 4
}

Since enumerations are integral data types underneath you can combine them in the usual fashion:

state = MyStates.CanBeSold | MyStates.CanBeExchanged

Note that this only works when the enum values are powers of two (as Doug Ferguson pointed out in a comment), so they can be combined easily and don't overlap when multiple ones are set.

You can also define values as combinations of multiple other values:

 CanBeSoldOrBought = CanBeSold | CanBeBought

or

 CanBeSoldOrBought = 3

which then also works as expected. This can be seen for example for file permissions where ReadWrite usually is a combination of the Read and Write bits.

And yes, that's quite a common practice. The framework itself also uses it in several places.

The usual way to check for a particular bit being set is then

if ((state & MyStates.CanBeSold) != 0) { ... }
请叫√我孤独 2024-08-20 20:35:41

创建一个枚举,其中的值对应于整数中的位。添加 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)) ...

Create an enum where the values correspond to bits in an integer. Adding the Flags attribute enabled you to do some more bit operations on the enum values.

[Flags]
public enum CanBe {
  Sold = 1,
  Bought = 2,
  Exchanged = 4
}

Now you can just use the or operator between the values:

CanBe can = CabBe.Sold | CanBe.Exchanged.

You can add a state with the |= operator:

can |= CanBe.Sold;

Or several states:

can |= CanBe.Sold | CanBe.Bought;

You can keep a state with the &= operator:

can &= CanBe.Sold;

Or several states:

can &= CanBe.Sold | CanBe.Bought;

You can remove states by using the ~ operator to create a complement to a value:

can &= ~CabBe.Bough;

Or seveal states:

can &= ~(CabBe.Bough | CanBe.Exchanged);

You can check for a state using the & operator:

if ((can & CanBe.Sold) != 0) ...

Or several states at once:

if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...

Or check that several states are all set:

if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...
不必在意 2024-08-20 20:35:41

您也可以使用 .NET 中的位掩码来完成此操作。

在枚举中,您可以将状态定义为值

public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }

然后在对象中,您可以执行以下操作

if (item.State ^ ItemState.CanBeSold) ....

You can do this with bit masks in .NET too.

Within your enum you can define your states as values

public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }

Then within your object, you can do

if (item.State ^ ItemState.CanBeSold) ....
七七 2024-08-20 20:35:41

您可以使用指定每个位的 Flags 枚举

[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;

You can use a Flags enum with each bit specified

[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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文