У меня есть перечисление вроде:
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
Как я могу удалить синий цвет из цветов переменных?
У меня есть перечисление вроде:
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
Как я могу удалить синий цвет из цветов переменных?
Вам нужно &
его с помощью ~
(дополнение) 'BLUE'.
Оператор дополнения существенно меняет или "переворачивает" все биты для данного типа данных. Таким образом, если вы используете оператор AND
(&
) с некоторым значением (позвольте этому значению "X" ) и дополнением к одному или нескольким установленным битам (позвольте вызывать эти биты Q
и их дополнение ~Q
), оператор X & ~Q
очищает любые биты, которые были установлены в Q
из X
, и возвращает результат.
Итак, чтобы удалить или очистить бит BLUE
, вы используете следующий оператор:
colorsWithoutBlue = colors & ~Blah.BLUE
colors &= ~Blah.BLUE // This one removes the bit from 'colors' itself
Вы также можете указать несколько бит для очистки, как показано ниже:
colorsWithoutBlueOrRed = colors & ~(Blah.BLUE | Blah.RED)
colors &= ~(Blah.BLUE | Blah.RED) // This one removes both bits from 'colors' itself
или поочередно...
colorsWithoutBlueOrRed = colors & ~Blah.BLUE & ~Blah.RED
colors &= ~Blah.BLUE & ~Blah.RED // This one removes both bits from 'colors' itself
Итак, суммируем:
X | Q
устанавливает бит Q
X & ~Q
очищает бит Q
~X
flips/инвертирует все биты в X
Другие ответы верны, но для того, чтобы специально удалить синий из вышесказанного, вы должны написать:
colors &= ~Blah.BLUE;
And not
it...............................
Blah.RED | Blah.YELLOW ==
(Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;
Думал, что это может быть полезно для других людей, которые спотыкались здесь, как я.
Будьте осторожны с тем, как вы обрабатываете любые значения перечисления, которые вы можете установить, чтобы иметь value == 0 (иногда может быть полезно иметь состояние Unknown или Idle для перечисления). Это вызывает проблемы, связанные с этими операциями манипуляции бит.
Также, когда у вас есть значения перечисления, которые являются комбинациями другой мощности из 2 значений, например.
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
В этих случаях может потребоваться такой способ расширения, как это:
public static Colour UnSet(this Colour states, Colour state)
{
if ((int)states == 0)
return states;
if (states == state)
return Colour.None;
return states & ~state;
}
А также эквивалентный метод IsSet, который обрабатывает объединенные значения (хотя и немного хакерским способом)
public static bool IsSet(this Colour states, Colour state)
{
// By default if not OR'd
if (states == state)
return true;
// Combined: One or more bits need to be set
if( state == Colour.Orange )
return 0 != (int)(states & state);
// Non-combined: all bits need to be set
return (states & state) == state;
}
Как насчет xor (^)?
Учитывая, что FLAG, который вы пытаетесь удалить, есть, он будет работать. Если нет, вам нужно будет использовать &.
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
colors = (colors ^ Colour.RED) & colors;
Вы можете использовать это:
colors &= ~Blah.RED;
Чтобы упростить перечисление флага и сделать его лучше читаемым, избегая кратных, мы можем использовать сдвиг битов. (Из хорошей статьи " Завершение великой дискуссии о флагах Enum")
[FLAG]
Enum Blah
{
RED = 1,
BLUE = 1 << 1,
GREEN = 1 << 2,
YELLOW = 1 << 3
}
а также очистить все биты
private static void ClearAllBits()
{
colors = colors & ~colors;
}