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

时间:2019-04-24 08:09:22

标签: c# enums gethashcode enum-flags

我有标志类型为Enum的每个元素,如下所示

[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

1 个答案:

答案 0 :(得分:2)

GetHashCode返回枚举值喜欢的任何值,只要它总是返回相同的值,就完全有效。

尽管已定义实现,但我怀疑A6获得64和A6 | A5获得0的原因归结于GetHashCode类型的long的实现。由于GetHashCode需要返回一个int(32位),因此它必须做一些额外的处理来对long(64位)进行哈希处理。

如果查看Long.GetHashCode的参考源实现,您会发现它的高32位与低32位互斥或。对于A6的{​​{1}},将是0x4000000000的{​​{1}}(64)。

对于0x40 | 0x00,您将得到0x40,当对高32位与低32位进行异或时,将为A6 | A5,这将给您0。 / p>