Хорошая практика GetHashCode?

Для проекта Delphi (построенного с помощью RAD Studio XE7) я хочу создать словарь кистей. Каждый элемент словаря содержит объект TMyBrush в качестве ключа, описывающего извлекаемую кисть, и кисть GDI+ в качестве значения.

Класс TMyBrush содержит 3 поля.

  • Перечисленный тип для определения типа кисти (сплошная, градиентная,...)
  • Класс TBrushInfo, описывающий содержимое кисти (цвет, режим обтекания и т. д.).
  • TRect, представляющий поле зажима

В своем словаре я хочу получить кисть на основе ее характеристик, а не ее экземпляра. Например, я хочу получить черную сплошную кисть из своего словаря, создав локальный экземпляр TMyBrush, настроив его на черную сплошную и получив соответствующее значение GDI+ с помощью функции TryGetValue(). Для этого я создал TMyBrushComparer.

Написание функции Equals() для меня не проблема. Однако я не знаю, как лучше всего писать функцию GetHashCode(). Я бы написал такую ​​функцию:

function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
    Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;

однако я чувствую, что это не очень хорошая практика, верно? Итак, как лучше всего написать хорошую функцию GetHashCode() для моего TMyBrushComparer?

С Уважением


person Jean-Milost Reymond    schedule 10.12.2016    source источник


Ответы (1)


Код в вопросе хэширует адрес объекта, а не его значение, и поэтому не соответствует вашему определению равенства.

Ваше определение равенства состоит в том, что три поля равны. Ваша хэш-функция должна соответствовать этому определению. Хэшируйте каждое из трех полей и объединяйте значения, например, используя описанный здесь подход: https://stackoverflow.com/a/263416/505088

Два из ваших полей являются типами значений. Их легко хешировать, чтобы сопоставить идентичность значения. Информационное поле кисти похоже на эталонный тип. Итак, снова вам нужно решить, какую форму идентичности вы хотите (ссылочная идентичность, идентичность значения или, возможно, что-то еще), а затем реализовать проверку на соответствие и хэш.

person David Heffernan    schedule 10.12.2016