我有一个枚举:
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;
我如何从可变颜色中移除蓝色?
当前回答
要切换标志,您可以使用duckface操作符,而不必使用~反转位
color ^= Color.Red; // unset Color.Red
or
color ^= (Color.Red | Color.Blue); // toggle both Red and Blue
但是,这将切换标志,而不是清除它。
正如@daniil-palii所提到的那样,编辑以确保正确性
其他回答
要切换标志,您可以使用duckface操作符,而不必使用~反转位
color ^= Color.Red; // unset Color.Red
or
color ^= (Color.Red | Color.Blue); // toggle both Red and Blue
但是,这将切换标志,而不是清除它。
正如@daniil-palii所提到的那样,编辑以确保正确性
你可以用这个:
colors &= ~Blah.RED;
为了简化标志枚举,并通过避免倍数来更好地读取,我们可以使用位移位。 (摘自一篇好文章《结束关于旗帜的大争论》)
[FLAG]
Enum Blah
{
RED = 1,
BLUE = 1 << 1,
GREEN = 1 << 2,
YELLOW = 1 << 3
}
还要清除所有比特
private static void ClearAllBits()
{
colors = colors & ~colors;
}
那么xor(^)呢?
考虑到你想要移除的旗帜就在那里,它会起作用。如果不是,则必须使用&。
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;
我想这对其他像我一样跌跌撞撞来到这里的人可能有用。
注意如何处理可能设置为值== 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;
}