C# 在标志上使用按位运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/530077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 06:57:36  来源:igfitidea点击:

Using Bitwise operators on flags

c#.netbit-manipulationbit-fields

提问by Malfist

I have four flags

我有四个标志

Current = 0x1  
Past = 0x2  
Future = 0x4  
All = 0x7

Say I receive the two flags Past and Future (setFlags(PAST | FUTURE)). How can I tell if Pastis in it? Likewise how can I tell that Currentis not in it? That way I don't have to test for every possible combination.

假设我收到两个标志 Past 和 Future ( setFlags(PAST | FUTURE))。我怎么知道它Past是否在里面?同样,我怎么能说那Current不在里面呢?这样我就不必测试每种可能的组合。

采纳答案by Marc Gravell

If you want all bits in the test mask to match:

如果您希望测试掩码中的所有位都匹配:

if((value & mask) == mask) {...}

If you want any single bit in the test mask to match:

如果您希望测试掩码中的任何单个位匹配:

if((value & mask) != 0) {...}

The difference is most apparent when you are testing a value for multiple things.

当您测试多个事物的值时,差异最为明显。

To test for exclusion:

要测试排除:

if ((value & mask) == 0) { }

回答by Peter

you could use AND on it and check if the result is the same as you and with?

你可以在上面使用 AND 并检查结果是否与你和 with 相同?

回答by Misko

if ((flags & PAST) == PAST)
{
  // PAST is there
}

if ((flags & CURRENT) != CURRENT)
{
  // CURRENT is not there
}

回答by Samantha Branham

(value & Current) == Current

回答by Vilx-

First of all - use enums with FlagAttribute. That's what it's for.

首先 - 将枚举与 FlagAttribute 一起使用。这就是它的用途。

[Flags]
public enum Time
{
    None = 0
    Current = 1,
    Past = 2,
    Future = 4
    All = 7
}

Testing then is done like this:

然后测试是这样完成的:

if ( (x & Time.Past) != 0 )

Or this:

或这个:

if ( (x & Time.Past) == Time.Past )

The latter will work better if "Past" was a combination of flags and you wanted to test them all.

如果“过去”是标志的组合并且您想对它们全部进行测试,则后者会更好地工作。

Setting is like this:

设置是这样的:

x |= Time.Past;

Unsetting is like this:

取消设置是这样的:

x &= ~Time.Past;

回答by Brian Rasmussen

You may also want to add an extension methodlike this

您可能还需要添加一个扩展方法是这样

  enum states {
     Current = 0x1,
     Past = 0x2,
     Future = 0x4,
     All = 0x7
  };

  static bool Is(this states current, states value) {
     return (current & value) == value;
  }

then you can do:

那么你可以这样做:

 if(state.Is(states.Past)) {
    // Past
 }

回答by Kody

An addendum to Marc Gravell and Vilx-'s answer:

Marc Gravell 和 Vilx- 的回答的附录:

Your flagged enum shouldn't specify the amount for "All", it should just include your existing values. This goes for any calculated values.

您标记的枚举不应指定“全部”的数量,它应该只包括您现有的值。这适用于任何计算值。

[Flags]
public enum Time
{
    None = 0,
    Current = 1,
    Past = 2,
    Future = 4,
    All = Current | Past | Future
}

Note that Vilx- removed the use of Hexadecimal for values. This is important because once you're past 0x8, your values will have to comply with Hex. You should just stay in decimal.

请注意,Vilx- 删除了对值使用十六进制。这很重要,因为一旦超过 0x8,您的值就必须符合十六进制。你应该只保留十进制。

EDIT:I also want to add that you can use bit shifting rather than hex/decimal.

编辑:我还想补充一点,您可以使用位移位而不是十六进制/十进制。

This looks like:

这看起来像:

[Flags]
public enum Time
{
    None = 0,
    Current = 1,
    Past = 1 << 1, // 2, 10 binary
    Future = 1 << 2, // 4, 100 binary
    All = Current | Past | Future
}

回答by Ogglas

If you use .NET 4 or later I prefer to do this, cleaner imao:

如果您使用 .NET 4 或更高版本,我更喜欢这样做,更干净的 imao:

[Flags]
public enum Time
{
    None = 0
    Current = 1,
    Past = 2,
    Future = 4
}

myProp = Time.Past | Time.Future;

if (myProp.HasFlag(Time.Past))
{
    // Past is set...
}