删除枚举标志

Ove*_*ive 0 c# enums bit-manipulation

我对有点删除枚举标志感到有点困惑.

让我举一个例子,假设我们有一个看起来像这样的枚举

[Flags]
enum Letter 
{
    A = 1, // 1
    B = 2, // 10
    C = 4  // 100
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想让变量保持Letter.AB我可以做的标志foo = Letter.A | Letter.B.现在这对我来说很有意义,我可以计算一下它会有意义:

   01
OR 10
 = 11 = 3 = 1 + 2 = A + B = AB
Run Code Online (Sandbox Code Playgroud)

当谈到删除标志时,我很困惑,直觉上我想要做的是使用XOR运算符这样做,如下所示:

bar = Letter.A | Letter.B | Letter.C // Set bar to ABC
// Now let's remove everything but Letter.C
bar = bar ^ (Letter.A | Letter.B)
Run Code Online (Sandbox Code Playgroud)

手动计算应该产生:

    111
XOR 011
  = 100 = 4 = C = ABC - (A + B) = 7 - (1 + 2)
Run Code Online (Sandbox Code Playgroud)

但这并不是人们在删除枚举标志时所做的事情,而是使用AND运算符,这对我来说毫无意义.使用XOR运算符删除枚举标志有什么缺点吗?显然必须有一些我在这里看不到的东西,所以详细的澄清将非常值得赞赏!:)

Jon*_*eet 8

是的,XOR运算符的问题在于,除非你知道你已经拥有了所有其余的标志,否则它只会翻转它们.所以你的XOR操作不是"除了C之外的全部" - 它是"切换A和B的值".(因此,如果输入为"A,C",则最终会以"B,C"结尾.)

&被使用是因为它是掩盖的.基本思想是你得到一个只包含你想要的位的值,然后用你的输入值对该值进行按位AND屏蔽它.

要删除一个特定标志(而不是保留该特定标志),通常使用~运算符创建"除该标志之外的所有标志"的掩码.例如:

var mask = ~Letter.A;
var newValue = originalValue & mask; // All previous values other than A
Run Code Online (Sandbox Code Playgroud)