In this question, I use xor operator between enum with [Flags] attribute as following:
[Flags]
enum QueryFlag
{
  None = 0x1,
  ByCustomer = 0x2,
  ByProduct = 0x4,
  ByDate = 0x8
}
QueryFlag flags = QueryFlag.ByCustomer | QueryFlag.ByProduct;
To add an QueryFlag, of course we should use | operator.
flags |= QueryFlag.ByDate;
To remove one, I have a different way with Dan Tao's answer. I'm using:
flags ^= QueryFlag.ByProduct;
while he is using:
flags &= ~QueryFlag.ByProduct;
Obviously his answer is correct and easy to understand. I thought I made a mistake. But after a deep thought I got:
a,b         a^b         a&(~b)
0,0          0           0
0,1          1           0   //the difference
1,0          1           1
1,1          0           0
And now I knew my mistake. ^ is wrong when you try to remove one item which doesn't exist.
QueryFlag q = QueryFlag.ByCustomer | QueryFlag.ByDate;
//try to remove QueryFlag.ByProduct which doesn't exist in q
q ^ QueryFlag.ByProduct    //equals to add ByProduct to q, wrong!
q & (~QueryFlag.ByProduct) // q isn't changed, remain the original value. correct!
But here I got another question: how can I know if q contains one item? Base on Dan Tao's answer I wrote an extension:
public static bool Contains(this QueryFlag flags, QueryFlag flag)
{
   return (flags & (~flag)) != flags;
}
That is, if flags is not changed after removing flag from flags, we know flag is not in flags! It seems correct when:
(QueryFlag.ByProduct | QueryFlag.ByDate).Contains(QueryFlag.None)   //false
(QueryFlag.ByProduct | QueryFlag.ByDate).Contains(QueryFlag.ByDate)  //true
But in fact:
(QueryFlag.ByProduct | QueryFlag.ByDate).Contains(QueryFlag.ByDate | QueryFlag.ByCustomer) //true, but I suppose it's false
I know the reason why it's false, how can I improve it? It's the first question.
The second: I want to make the .Contains generic to more enum with [Flags] attribute.
public static bool Contains<T>(this T flags, T flag) where T : Enum//with [Flags]
{
    return (flags & (~flag)) != flags;
}
Probably it's impossible to constrain T with attribute marked. But even I remove this constraint I get a compile error which says operator ~ can't be applied to type T. Why and how to resolve?
 
     
     
    