什么是枚举定义中的代字号(〜)?

我总是感到惊讶,即使现在一直使用C#,我仍然设法find我不知道的事情…

我已经试过在网上search这个,但是在search中使用“〜”对我来说不是很好,我也没有在MSDN上find任何东西(不是说它不存在)

我最近看了这段代码,代字符(〜)是什么意思?

/// <summary> /// Enumerates the ways a customer may purchase goods. /// </summary> [Flags] public enum PurchaseMethod { All = ~0, None = 0, Cash = 1, Check = 2, CreditCard = 4 } 

我有点惊讶地看到它,所以我试图编译它,它的工作…但我仍然不知道它是什么意思/做什么。 任何帮助?

〜是一元补码操作符 – 它翻转操作数的位。

 ~0 = 0xFFFFFFFF = -1 

在二进制补码运算中, ~x == -x-1

〜运算符可以在几乎所有借用C语言的语言中find,包括Objective-C / C ++ / C#/ Java / Javascript。

我会认为:

 [Flags] public enum PurchaseMethod { None = 0, Cash = 1, Check = 2, CreditCard = 4, All = Cash | Check | CreditCard } 

会更清楚一点。

 public enum PurchaseMethod { All = ~0, // all bits of All are 1. the ~ operator just inverts bits None = 0, Cash = 1, Check = 2, CreditCard = 4 } 

由于C#中的两个补码, ~0 == -1 ,在二进制表示中所有位都是1的数字。

它比

 All = Cash | Check | CreditCard 

解决scheme,因为如果您稍后添加其他方法,请说:

 PayPal = 8 , 

你已经完成了波浪号 – 所有,但必须改变与其他的全线。 所以它后来不太容易出错。

问候

只是一个侧面说明,当你使用

 All = Cash | Check | CreditCard 

您有额外的好处, Cash | Check | CreditCard Cash | Check | CreditCard Cash | Check | CreditCard将评估为All而不是包含所有值的其他值(-1)不等于全部。 例如,如果在UI中使用三个checkbox

 [] Cash [] Check [] CreditCard 

并将它们的值相加,并且用户全部选中它们,则会在结果枚举中看到All

对于发现这个问题的其他人来说,我有一个快速的例子来分享。 在Mono文档中详细描述的实现paint方法的以下片段使用~效果非常好:

 PaintCells (clipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.SelectionBackground); 

没有~运算符,代码可能看起来像这样:

 PaintCells (clipBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border | DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.Focus); 

…因为枚举看起来像这样:

 public enum DataGridViewPaintParts { None = 0, Background = 1, Border = 2, ContentBackground = 4, ContentForeground = 8, ErrorIcon = 16, Focus = 32, SelectionBackground = 64, All = 127 // which is equal to Background | Border | ... | Focus } 

注意这个枚举类似于肖恩·布莱特的答案?

我认为对我来说最重要的是, ~是一个枚举中的运算符,就像它在一个正常的代码行中一样。

这是一个补充运算符,这是我经常提到的按位运算符的文章

http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx

另外MSDN在他们的枚举文章中使用它来certificate它更好用

http://msdn.microsoft.com/en-us/library/cc138362.aspx

我个人使用的替代方法,与@Sean Bright的回答相同,但对我来说更好,这是一个:

 [Flags] public enum PurchaseMethod { None = 0, Cash = 1, Check = 2, CreditCard = 4, PayPal = 8, BitCoin = 16, All = Cash + Check + CreditCard + PayPal + BitCoin } 

注意这些数字的二进制性质,它们都是两个幂,使得下面的断言是正确的: (a + b + c) == (a | b | c) 。 和恕我直言, +看起来更好。

我已经做了一些试验,发现它可能有缺陷。 考虑这个LINQPad代码片断,它显示了当所有的值都在一起时,所有枚举值的行为并不像预期的那样。

 void Main() { StatusFilterEnum x = StatusFilterEnum.Standard | StatusFilterEnum.Saved; bool isAll = (x & StatusFilterEnum.All) == StatusFilterEnum.All; //isAll is false but the naive user would expect true isAll.Dump(); } [Flags] public enum StatusFilterEnum { Standard =0, Saved =1, All = ~0 } 

只是想添加,如果你使用[Flags]枚举,那么使用按位左移运算符可能会更方便,就像这样:

 [Flags] enum SampleEnum { None = 0, // 0 First = 1 << 0, // 1b = 1d Second = 1 << 1, // 10b = 2d Third = 1 << 2, // 100b = 4d Fourth = 1 << 3, // 1000b = 8d All = ~0 // 11111111b }