Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected behavior between [Flags] enum : long vs [Flags] enum : ulong

Compiles but shouldn't

[Flags]
enum TransactionData : long  // 64 bits.  Last bit is sign bit, but I'm putting data there
{
    None = 0,
    Color1 = 1 << 63,
}

Errors but shouldn't

[Flags]
enum TransactionData : ulong  // 64 bits. No sign bit.  Not allowed to put data there
{
    None = 0,
    Color1 = 1 << 63,
}

Compiler Error Text:

-2147483648 cannot be converted to a ulong

Question:

I would expect the opposite to occur. Can anyone explain why this is?

Also how I can print this flags attribute to a byte[] for inspection?

 var eee  = TransactionData.None | TransactionData.Color1
 // How do I convert eee to byte[]?
like image 521
makerofthings7 Avatar asked Mar 12 '14 22:03

makerofthings7


1 Answers

Note that 1 << 63 isn't a ulong or even a long. The compiler interprets it as an int. Observe the following example:

enum TransactionData : long
{
    None = 0,
    Color1 = 1 << 31,
    Color2 = 1 << 63,
}

Console.WriteLine(TransactionData.Color1 == TransactionData.Color2); // True

However, you can coerce the compiler into interpreting it as a ulong by adding ul to the end:

enum TransactionData : ulong
{
    None = 0,
    Color1 = 1ul << 63,
}

Although many people prefer using an upper case L because the lowercase l looks a lot like a number 1. A full list of what suffixes are supported by the compiler can be found here.

Also, I should point out that 1ul << 63 is actually 64 bits wide (it's one bit, shifted by 63 bits).

like image 169
p.s.w.g Avatar answered Oct 11 '22 14:10

p.s.w.g