在标志上使用按位运算符

我有四面旗帜

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

假设我收到过去和未来的两个标志( setFlags(PAST | FUTURE) )。 如何判断Past是否在其中? 同样,我如何判断Current不在其中? 这样我就不必测试每种可能的组合。

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

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

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

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

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

要测试排除:

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

首先 – 使用带有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; 

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

  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 } 
 if ((flags & PAST) == PAST) { // PAST is there } if ((flags & CURRENT) != CURRENT) { // CURRENT is not there } 
 (value & Current) == Current 

Marc Gravell的补遗和Vilx的答案:

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

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

请注意,Vilx-删除了使用hex值。 这很重要,因为一旦超过0x8,您的值必须符合Hex。 你应该保持小数。

如果您使用.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... } 

你可以使用AND并检查结果是否和你一样?