GetHashCode возвращает одно и то же значение для различных перечислений битовых флагов - PullRequest
1 голос
/ 24 апреля 2019

У меня есть флаг типа 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 не равен нулю.

Здесь в этом случае я получаю то же значение кода Has, возвращаемое для элементов 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 Ответ

2 голосов
/ 24 апреля 2019

Совершенно верно для GetHashCode возвращать любое значение, которое ему нравится, для значения перечисления, если оно всегда возвращает одно и то же значение.

Хотя это определено реализацией, я подозреваю, что причина, по которой вы получаете 64для A6 и 0 для A6 | A5 до реализации GetHashCode для типа long.Поскольку GetHashCode необходимо вернуть int (что составляет 32 бита), ему потребуется выполнить дополнительную обработку для хеширования long (что составляет 64 бита).

Если вы посмотрите наРеализация эталонного источника для Long.GetHashCode , вы увидите, что он является исключительным или старшими 32 битами с младшими 32 битами.Для A6, который равен 0x4000000000, это будет 0x40 | 0x00, что составляет 0x40 (64).

Для A6 | A5 вы получите 0x4000000040, что при старших 32 битахxor'd с младшими 32 битами будет 0x40 | 0x40, что даст вам 0.

...