简体   繁体   中英

GetHashCode returning same Value for the different Bit Flag Enums

I have Flag type Enum with bitwise representation for each element as below

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

I Crated this as Flags Enum because I need to store the combination of this entries. The problem I am facing here, I do have a generic code to check the HasCode and then do some operation if HashCode is not zero.

Here in this case, I get same Has code value returned for elements A5 and A6 which is returned as 64 (binary value for 0x40).

And if I have a combination of A5 and A6, it gives me a hashcode of zero. Can some one please advise how I can handle this situation to avoid getting zero value for this combination and why is that both giving same hash code as that of A5.

Below code shows how it is represented.

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();
}

And Result for this is as below: 在此处输入图片说明

It's perfectly valid for GetHashCode to return any value it likes for an enum value, as long as it always returns the same value.

Although it's implementation defined, I suspect the reason you are getting 64 for A6 and 0 for A6 | A5 A6 | A5 is down to the implementation of GetHashCode for the long type. As GetHashCode needs to return an int (which is 32 bits) it is going to have to do some additional processing to hash a long (which is 64 bits).

If you look at the reference source implementation for Long.GetHashCode you'll see that it exclusive-or's the upper 32 bits with the lower 32 bits. For A6 which is 0x4000000000 this will be 0x40 | 0x00 0x40 | 0x00 which is 0x40 (64).

For A6 | A5 A6 | A5 you'll end up with 0x4000000040 , which when the upper 32 bits are xor'd with the lower 32 bits will be 0x40 | 0x40 0x40 | 0x40 which will give you 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM