如何删除OR'd枚举的项目?

时间:2011-01-24 02:51:35

标签: c# enums

我有一个类似的枚举:

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

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

如何从变色中删除蓝色?

8 个答案:

答案 0 :(得分:271)

您需要&使用~(补充)'BLUE'。

补码运算符实质上反转或“翻转”给定数据类型的所有位。因此,如果您使用AND运算符(&)具有某个值(让我们调用该值'X')和一个或多个设置位的补码(让我们调用那些位{{1} }和它们的补集Q),语句~Q清除X & ~QQ中设置的任何位并返回结果。

因此,要删除或清除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
  • 中的所有位

答案 1 :(得分:41)

其他答案是正确的,但要专门从上面删除蓝色,你会写:

colors &= ~Blah.BLUE;

答案 2 :(得分:8)

And not它................................

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

答案 3 :(得分:7)

认为这可能对像我这样偶然发现的其他人有用。

小心你如何处理你可能设置为具有值== 0的任何枚举值(有时为枚举设置一个未知或空闲状态会很有帮助)。当依赖这些位操作操作时,它会导致问题。

此外,当您的枚举值是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方法(尽管有点像hacky)

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;
}

答案 4 :(得分:2)

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;

答案 5 :(得分:0)

您可以使用:

colors &= ~Blah.RED; 

答案 6 :(得分:0)

为了简化标志枚举并避免重复使用,可能会更好,我们可以使用位移。 (摘自Ending the Great Debate on Enum Flags的精彩文章)

[FLAG]
Enum Blah
{
   RED = 1,
   BLUE = 1 << 1,
   GREEN = 1 << 2,
   YELLOW = 1 << 3
}

并清除所有位

private static void ClearAllBits()
{
    colors = colors & ~colors;
}

答案 7 :(得分:0)

如果你使用duckface操作符,你就不必用~来反转位

color ^= Color.Red; // unset Color.Red

color ^= (Color.Red | Color.Blue); // unset both Red and Blue