问题
I'm a little bit puzzled by the removal of enum flags to be perfectly honest.
Let me make an example, let's say we have an enum that looks like this
[Flags]
enum Letter
{
A = 1, // 1
B = 2, // 10
C = 4 // 100
}
Now if I want to make a variable hold the flags Letter.AB
I could do foo = Letter.A | Letter.B
. Now this makes sense to me, I can calculate this and it will make sense:
01
OR 10
= 11 = 3 = 1 + 2 = A + B = AB
When it comes to removing flags, I am puzzled however, intuitively what I would like to do is use the XOR operator to do so, like this:
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)
Calculating this by hand should yield:
111
XOR 011
= 100 = 4 = C = ABC - (A + B) = 7 - (1 + 2)
But this isn't what people seem to do when they are removing enum flags, they use the AND operator which makes absolutely no sense to me. Is there any drawback to using the XOR operator for removing enum flags? There must obviously be something I'm not seeing here, so a detailed clarification would be appreciated greatly! :)
回答1:
Yes, the problem with the XOR operator is that unless you know that you've got all the rest of the flags, it will just flip them. So your XOR operation isn't "remove all but C" - it's "toggle the values of A and B". (So if the input was "A,C" you'd end up with "B,C", for example.)
&
is used because it's masking. The basic idea is that you get a value which contains just the bits you want, and then a bitwise AND of that value with your input value masks it.
To remove one specific flag (rather than retaining that specific flag), you'd typically use the ~
operator to create a mask of "all but that flag". For example:
var mask = ~Letter.A;
var newValue = originalValue & mask; // All previous values other than A
来源:https://stackoverflow.com/questions/26307124/removing-enum-flags