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

问题描述 投票:1回答:1

我有每个元素的按位表示的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();
}

结果如下:enter image description here

c# enums gethashcode enum-flags
1个回答
2
投票

GetHashCode返回枚举值所需的任何值都是完全有效的,只要它总是返回相同的值即可。

虽然它是实现定义的,但我怀疑你为A6得到64而A6 | A5为0的原因是为GetHashCode类型执行long。由于GetHashCode需要返回一个int(32位),它将不得不做一些额外的处理来散列long(64位)。

如果你看一下Long.GetHashCode的参考源实现,你会看到它是独占的 - 或者是低32位的高32位。对于A6这是0x4000000000,这将是0x40 | 0x00,这是0x40(64)。

对于A6 | A5,你最终会得到0x4000000040,当高32位与低32位xor'd时将是0x40 | 0x40,这将给你0。

© www.soinside.com 2019 - 2024. All rights reserved.