[Flags]enum:long与[Flags]numm:ulong之间的意外行为

本文关键字:Flags 意外 之间 enum long numm ulong | 更新日期: 2023-09-27 17:49:59

编译,但不应编译

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

错误但不应该

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

编译器错误文本:

-2147483648无法转换为ulong

问题:

我预计会出现相反的情况。有人能解释为什么会这样吗?

此外,我如何将此标志属性打印到byte[]进行检查?

 var eee  = TransactionData.None | TransactionData.Color1
 // How do I convert eee to byte[]?

[Flags]enum:long与[Flags]numm:ulong之间的意外行为

请注意,1 << 63不是ulong,甚至不是long。编译器将其解释为int。观察以下示例:
enum TransactionData : long
{
    None = 0,
    Color1 = 1 << 31,
    Color2 = 1 << 63,
}
Console.WriteLine(TransactionData.Color1 == TransactionData.Color2); // True

但是,您可以通过在末尾添加ul来强制编译器将其解释为ulong

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

尽管许多人更喜欢使用大写L,因为小写l看起来很像数字1。编译器支持的后缀的完整列表可以在这里找到。

此外,我应该指出,1ul << 63实际上是64位宽(它是一位,偏移了63位(。