C# 枚举定义中的波浪号 (~) 是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/387424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:31:30  来源:igfitidea点击:

What is the tilde (~) in the enum definition?

c#enumslanguage-featuresenumeration

提问by Hugoware

I'm always surprised that even after using C# for all this time now, I still manage to find things I didn't know about...

我总是很惊讶,即使在使用 C# 这么久之后,我仍然设法找到我不知道的东西......

I've tried searching the internet for this, but using the "~" in a search isn't working for me so well and I didn't find anything on MSDN either (not to say it isn't there)

我试过在互联网上搜索这个,但是在搜索中使用“~”对我来说不是很好,我也没有在 MSDN 上找到任何东西(不是说它不存在)

I saw this snippet of code recently, what does the tilde(~) mean?

最近看到这段代码,波浪号(~)是什么意思?

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

I was a little surprised to see it so I tried to compile it, and it worked... but I still don't know what it means/does. Any help??

看到它我有点惊讶,所以我尝试编译它,它起作用了……但我仍然不知道它的含义/作用。有什么帮助吗??

采纳答案by Jimmy

~ is the unary one's complement operator -- it flips the bits of its operand.

~ 是一元的补码运算符——它翻转其操作数的位。

~0 = 0xFFFFFFFF = -1

in two's complement arithmetic, ~x == -x-1

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

the ~ operator can be found in pretty much any language that borrowed syntax from C, including Objective-C/C++/C#/Java/Javascript.

~ 操作符几乎可以在任何借用 C 语法的语言中找到,包括 Objective-C/C++/C#/Java/Javascript。

回答by Johannes Schaub - litb

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

Because of two complement in C#, ~0 == -1, the number where all bits are 1 in the binary representation.

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

回答by missaghi

It's a complement operator, Here is an article i often refer to for bitwise operators

这是一个补码运算符,这是我经常参考的关于按位运算符的文章

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

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

Also msdn uses it in their enums article which demonstrates it use better

msdn 在他们的 enums 文章中也使用了它,这表明它使用得更好

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

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

回答by Sean Bright

I'd think that:

我会认为:

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

Would be a bit more clear.

会清楚一些。

回答by blabla999

Its better than the

它比

All = Cash | Check | CreditCard

solution, because if you add another method later, say:

解决方案,因为如果您稍后添加另一个方法,请说:

PayPal = 8 ,

you will be already done with the tilde-All, but have to change the all-line with the other. So its less error-prone later.

您将已经完成波浪线-All,但必须将所有线更改为另一个。所以以后更不容易出错。

regards

问候

回答by configurator

Just a side note, when you use

只是一个旁注,当你使用

All = Cash | Check | CreditCard

you have the added benefit that Cash | Check | CreditCardwould evaluate to Alland not to another value (-1) that is not equal to all while containing all values. For example, if you use three check boxes in the UI

你有额外的好处,它Cash | Check | CreditCard会评估为All而不是另一个值(-1),它不等于所有,同时包含所有值。例如,如果您在 UI 中使用三个复选框

[] Cash
[] Check
[] CreditCard

and sum their values, and the user selects them all, you would see Allin the resulting enum.

并对它们的值求和,然后用户将它们全部选中,您将All在结果枚举中看到。

回答by Mike

For others who found this question illuminating, I have a quick ~example to share. The following snippet from the implementation of a paint method, as detailed in this Mono documentation, uses ~to great effect:

对于发现这个问题很有启发性的其他人,我有一个简单的~例子可以分享。如本 Mono 文档中所详述的,以下来自 Paint 方法实现的片段使用~效果很好:

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

Without the ~operator, the code would probably look something like this:

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

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

... because the enumeration looks like this:

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

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
}

Notice this enum's similarity to Sean Bright's answer?

注意到这个枚举与 Sean Bright 的答案的相似之处了吗?

I think the most important take away for me is that ~is the same operator in an enum as it is in a normal line of code.

我认为对我来说最重要的一点~是枚举中的运算符与普通代码行中的运算符相同。

回答by Camilo Martin

The alternative I personally use, which does the same thing than @Sean Bright's answer but looks better to me, is this one:

我个人使用的替代方案,与@Sean Bright 的答案做同样的事情,但对我来说看起来更好,是这个:

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

Notice how the binary nature of those numbers, which are all powers of two, makes the following assertion true: (a + b + c) == (a | b | c). And IMHO, +looks better.

请注意这些数字的二进制性质(它们都是 2 的幂)如何使以下断言为真:(a + b + c) == (a | b | c)。恕我直言,+看起来更好。

回答by Gavin

I have done some experimenting with the ~ and find it that it could have pitfalls. Consider this snippet for LINQPad which shows that the All enum value does not behave as expected when all values are ored together.

我对 ~ 做了一些实验,发现它可能有陷阱。考虑 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 
}

回答by sad_robot

Just want to add, if you use [Flags] enum, then it may be more convenient to use bitwise left shift operator, like this:

只是想补充一下,如果你使用[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
}