Использование побитовых операторов на флагах
У меня есть четыре флажка
Current = 0x1
Past = 0x2
Future = 0x4
All = 0x7
Скажем, я получаю два флага "Прошлое и будущее" (setFlags(PAST | FUTURE)
). Как я могу определить, есть ли в нем Past
? Аналогично, как я могу сказать, что Current
не в нем? Таким образом, мне не нужно проверять все возможные комбинации.
Ответы
Ответ 1
Если вы хотите, чтобы все биты в тестовой маске соответствовали:
if((value & mask) == mask) {...}
Если вы хотите, чтобы любой бит в тестовой маске соответствовал:
if((value & mask) != 0) {...}
Разница наиболее очевидна, когда вы тестируете значение для нескольких вещей.
Чтобы проверить исключение:
if ((value & mask) == 0) { }
Ответ 2
Прежде всего - используйте перечисления с 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;
Ответ 3
Вы также можете добавить метод расширения, как этот
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
}
Ответ 4
if ((flags & PAST) == PAST)
{
// PAST is there
}
if ((flags & CURRENT) != CURRENT)
{
// CURRENT is not there
}
Ответ 5
(value & Current) == Current
Ответ 6
Добавление к Marc Gravell и Vilx -...
В указанном перечислении не указывается сумма для "Все", она должна включать только ваши существующие значения. Это относится ко всем рассчитанным значениям.
[Flags]
public enum Time
{
None = 0
Current = 1,
Past = 2,
Future = 4,
All = Current | Past | Future
}
Обратите внимание, что Vilx - удалил использование шестнадцатеричных значений. Это важно, потому что, как только вы пройдете 0x8, ваши ценности должны будут соответствовать Hex. Вы должны просто оставаться в десятичной форме.
Ответ 7
вы можете использовать AND на нем и проверить, совпадает ли результат с вами и с?