在标志上使用按位运算符
我有四面旗帜
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并检查结果是否和你一样?