GetHashCode 为不同的位标志枚举返回相同的值

GetHashCode returning same Value for the different Bit Flag Enums

我有 Flag 类型枚举,每个元素的按位表示如下

[DataContract]
[Flags]
public enum TestProduct : long
{
    [EnumMember]
    A1 = 0x1,
    [EnumMember]
    A2 = 0x2,
    [EnumMember]
    A3 = 0x4,
    [EnumMember]
    A4 = 0x8,
    [EnumMember]
    A5 = 0x40,
    [EnumMember]
    A6 =0x4000000000,
}

我将其创建为 Flags Enum,因为我需要存储这些条目的组合。我在这里面临的问题,我有一个通用代码来检查HasCode,然后在HashCode不为零的情况下进行一些操作。

在这种情况下,我得到相同的代码值返回元素 A5 和 A6,返回为 64(0x40 的二进制值)。

如果我有 A5 和 A6 的组合,它会给我一个零哈希码。 有人可以告诉我如何处理这种情况以避免此组合的值为零,以及为什么两者都提供与 A5 相同的哈希码。

下面的代码显示了它是如何表示的。

static void Main(string[] args)
{
    Console.Write("Hash Code for A5 is ");
    Console.WriteLine(Enums.TestProduct.A5.GetHashCode());
    Console.Write("Hash Code for A6 is ");
    Console.WriteLine(Enums.TestProduct.A6.GetHashCode());
    Console.Write("Hash Code for A6 | A5 is ");
    Console.WriteLine((Enums.TestProduct.A6 | Enums.TestProduct.A5).GetHashCode());
    Console.ReadLine();
}

结果如下:

对于枚举值 GetHashCode 到 return 它喜欢的任何值都是完全有效的,只要它总是 return 相同的值。

虽然它是实现定义的,但我怀疑你得到 64 for A6 和 0 for A6 | A5 的原因是 GetHashCode for the long 的实现类型。由于 GetHashCode 需要 return 一个 int(32 位),因此必须进行一些额外的处理来散列一个 long(64 位)。

如果您查看 Long.GetHashCode 的参考源实现,您会发现它是异或高 32 位与低 32 位。对于 A60x4000000000 这将是 0x40 | 0x000x40 (64).

对于 A6 | A5 你最终会得到 0x4000000040,当高 32 位与低 32 位异或时将是 0x40 | 0x40 这会给你 0 .