Вы можете использовать это:

я есть перечисление как:

public enum Blah
{
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16
}

Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;

Как я могу удалить синий цвет из переменных цветов?

 Nyerguds17 сент. 2017 г., 01:49
Небольшое примечание: побитовое перечисление в C # должно получить атрибут [Flags] над ним.
 ethane19 окт. 2017 г., 06:40
@ Nyerguds, не могли бы вы объяснить, почему он должен получить атрибут?
 Nyerguds19 окт. 2017 г., 11:41
Он обеспечивает лучшую поддержку IntelliSense при отладке, поскольку он распознает неизвестные значения перечисления как комбинации существующих значений.
 Sinjai27 февр. 2018 г., 04:06
Это также обеспечивает более значимое.ToString() стоимость. напримерRED, BLUE, YELLOW скорее, чем22.

Ответы на вопрос(6)

что это может быть полезно для других людей, которые наткнулись здесь, как я.

Будьте осторожны с обработкой любых значений перечисления, для которых вы можете установить значение == 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;
}
 Sverrir Sigmundarson02 мар. 2018 г., 20:41
Вы находитесь на правильном пути в вашем редакторе Синджай, сохраняя неустановленное значение == 0 фактически решает несколько проблем. Один из них - то, что вы упомянули, а другой - если вы сбросили все значения перечисления, тогда вам не нужен особый случай для «Unset», если он установлен на ноль. (например, если выRed & ~Red затем вы получите ноль, вам нужно будет иметь код для проверки этого случая и явно назначитьUnset стоимость)
 Sinjai02 мар. 2018 г., 20:53
Попался. Вы часто сталкиваетесь с неустановленными флагами?
 Sinjai28 февр. 2018 г., 11:28
Разве вы не можете просто Unset = 1 и использовать1, 2, 4, 8 как ваши ценности? Если вам нужно значение по умолчанию, для этого нужны конструкторы по умолчанию, верно? Мне нравится держать вещи настолько явными, насколько это возможно, для удобства чтения и полагаться на перечисление по умолчаниюdefault(int) (0) если ему не дано значение, несмотря на то, что информация, по-видимому, известна любому разработчику, в любом случае слишком коварна для моих вкусов. Редактировать: Ой, подождите, если Unset = 0 предотвратит что-тоUnset | Blue?
 Sverrir Sigmundarson28 февр. 2018 г., 09:10
Иметьnone или жеunknown или жеunset запись со значением == 0 во многих случаях является хорошей вещью, поскольку вы не всегда можете предположить, что определенное значение является набором по умолчанию, например если у вас есть только красный, синий и зеленый, вы будете использовать красный в качестве значения по умолчанию (например, значение, которое имеет перечисление при его создании, или пользователь не изменил его?)
 Sinjai27 февр. 2018 г., 04:36
Мне кажется, что более простое решение - избегать использования 0 в качестве флага. Я обычно устанавливаю флаг перечисления какэто, Я не понимаю, какую выгоду вы получите от указания состояния со значением 0. В конце концов, весь смысл в том, что вы можете позаботиться о дружественных для программиста именах (Red, Blue, Green) а не базовые ценности, да?
Решение Вопроса

& это с~ (дополнение) «СИНИЙ».

Оператор дополнения по существу инвертирует или «переворачивает» все биты для данного типа данных. Таким образом, если вы используете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 устанавливает бит (ы)QX & ~Q очищает битQ~X переворачивает / инвертирует все биты вX
 SLaks24 янв. 2011 г., 04:18
@Blank: правильно.
 Dave Jellison13 мая 2016 г., 18:28
Отличный ответ. Я думаю, что вы имеете в виду "& =" not "= &" в ваших примерах кода;)
 Blankman24 янв. 2011 г., 04:09
поэтому, если бы я хотел удалить больше, я бы просто сделал: & = ~ Blah.BLUE & ~ Blah.Green?
 Blankman30 янв. 2015 г., 02:45
как необычно, я просто думал, как сделать это еще раз около 5 дней назад :) Этот вопрос обновлен в моем почтовом ящике и вуаля!
 par24 янв. 2013 г., 21:56
Лучше этоcolors &= ~( Blah.BLUE | Blah.GREEN );

And not Это...............................

   (Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;

Учитывая, что 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.BLUE;
 Bitterblue21 янв. 2014 г., 16:46
Краткий и четкий ответ. Это лучшие ответы!
 Joseph04 нояб. 2017 г., 06:43
Сладкий. Коротко и точно

Вы можете использовать это:

colors &= ~Blah.RED; 

Ваш ответ на вопрос