我有四个标志
Current = 0x1
Past = 0x2
Future = 0x4
All = 0x7
说我收到过去和未来两个标志(setFlags(PAST | FUTURE)
)。如何判断Past
是否在其中?同样,我如何判断Current
不在其中?这样我就不必测试每种可能的组合。
答案 0 :(得分:43)
如果您希望测试掩码中的所有位匹配:
if((value & mask) == mask) {...}
如果您希望测试掩码中的任何一位匹配:
if((value & mask) != 0) {...}
当您测试多个事物的值时,差异最明显。
测试排除:
if ((value & mask) == 0) { }
答案 1 :(得分:29)
首先 - 使用带有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;
答案 2 :(得分: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
}
答案 3 :(得分:4)
if ((flags & PAST) == PAST)
{
// PAST is there
}
if ((flags & CURRENT) != CURRENT)
{
// CURRENT is not there
}
答案 4 :(得分:3)
如果您使用.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...
}
答案 5 :(得分:1)
Marc Gravell和Vilx的补遗 - 答案:
您标记的枚举不应指定"所有"的金额,它应该只包括您现有的值。这适用于任何计算值。
[Flags]
public enum Time
{
None = 0,
Current = 1,
Past = 2,
Future = 4,
All = Current | Past | Future
}
请注意,Vilx-删除了使用十六进制值。这很重要,因为一旦超过0x8,您的值必须符合Hex。你应该保持小数。
修改强> 我还想补充一点,你可以使用位移而不是十六进制/十进制。
这看起来像:
[Flags]
public enum Time
{
None = 0,
Current = 1,
Past = 1 << 1, // 2, 10 binary
Future = 1 << 2, // 4, 100 binary
All = Current | Past | Future
}
答案 6 :(得分:0)
(value & Current) == Current
答案 7 :(得分: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;
答案 8 :(得分:-1)
您可以使用AND并检查结果是否与您相同并使用?