30

我有四个标志

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

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

4

8 回答 8

47

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

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

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

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

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

要测试排除:

if ((value & mask) == 0) { }
于 2009-02-09T21:40:07.017 回答
32

首先 - 使用带有 FlagAttribute 的枚举。这就是它的用途。

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

然后测试是这样完成的:

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

或这个:

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

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

设置是这样的:

x |= Time.Past;

取消设置是这样的:

x &= ~Time.Past;
于 2009-02-09T21:38:25.460 回答
12

您可能还想添加这样的扩展方法

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

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

那么你可以这样做:

 if(state.Is(states.Past)) {
    // Past
 }
于 2009-02-09T21:45:22.650 回答
7

如果您使用 .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...
}
于 2018-04-20T14:08:28.283 回答
6

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

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

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

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

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

这看起来像:

[Flags]
public enum Time
{
    None = 0,
    Current = 1,
    Past = 1 << 1, // 2, 10 binary
    Future = 1 << 2, // 4, 100 binary
 // Example = 1 << 3, // 8, 1000 binary
 // Example = 1 << 4, // 16, 10000 binary
    All = Current | Past | Future
}
于 2014-09-22T19:15:12.640 回答
4
if ((flags & PAST) == PAST)
{
  // PAST is there
}

if ((flags & CURRENT) != CURRENT)
{
  // CURRENT is not there
}
于 2009-02-09T21:37:30.220 回答
0
(value & Current) == Current
于 2009-02-09T21:37:50.143 回答
0

我认为缺少的是除一个以外的“全部”

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

然后使用上面的标志枚举,你可以做

var notNow= Time&~Time.Current;
于 2020-08-17T11:23:07.457 回答