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

C#EnumsLanguage FeaturesEnumeration

C# Problem Overview


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...

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)

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??

C# Solutions


Solution 1 - C#

~ 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

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

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

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.

regards

Solution 5 - C#

Just a side note, when you use

All = Cash | Check | CreditCard

you have the added benefit that Cash | Check | CreditCard would evaluate to All and 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

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

Solution 6 - C#

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:

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?

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.

Solution 7 - C#

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

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

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

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

Solution 8 - C#

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

[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.

Solution 9 - C#

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.

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 
}

Solution 10 - C#

Each bit in [Flags] enum means something enabled (1) or disabled (0).
~ operator is used to invert all the bits of the number. Example: 00001001b turns into 11110110b.
So ~0 is used to create the value where all bits are enabled, like 11111111b for 8-bit enum.

Just want to add that for this type of enums it may be more convenient to use bitwise left shift operator, like this:

[Flags]
enum SampleEnum
{
    None   = 0,      // 0000b
    First  = 1 << 0, // 0001b
    Second = 1 << 1, // 0010b
    Third  = 1 << 2, // 0100b
    Fourth = 1 << 3, // 1000b
    All    = ~0      // 1111b
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhugowareView Question on Stackoverflow
Solution 1 - C#JimmyView Answer on Stackoverflow
Solution 2 - C#Sean BrightView Answer on Stackoverflow
Solution 3 - C#Johannes Schaub - litbView Answer on Stackoverflow
Solution 4 - C#blabla999View Answer on Stackoverflow
Solution 5 - C#configuratorView Answer on Stackoverflow
Solution 6 - C#MikeView Answer on Stackoverflow
Solution 7 - C#missaghiView Answer on Stackoverflow
Solution 8 - C#Camilo MartinView Answer on Stackoverflow
Solution 9 - C#GavinView Answer on Stackoverflow
Solution 10 - C#alukyView Answer on Stackoverflow