Объект как ключ в словаре. Безопасно ли?

Рейтинг: 1Ответов: 1Опубликовано: 29.07.2025

Надоело ссылаться на массив объектов в словаре, рискнул в новой версии Delphi задать класс этих объектов в качестве ключа:

  TReaction = class
    // тут почикано, чтоб место не занимало
  end;

  TData = array[1..25] of double;

  TReactionDic = TDictionary<TReaction, TData>;

В более старых версиях (не помню, уже каких) компилятор ругался на такое определение словаря, и меня это раздражало - record можно использовать, а объект - нет. Сейчас же всё прошло успешно. Это сильно облегчает логику передачи данных, но меня грызут сомнения - нет ли здесь какого-то скрытого подвоха?

Ответы

▲ 6Принят

Если пройти по цепочке вызовов при добавлении нового элемент в словарь, то доберёмся до TObject.GetHashCode, внутри которого берётся простенький хэш от адреса объекта

Result := Integer(Self);
Result := Result xor (Result shr 4);

Таким образом, ключ зависит не от внутреннего содержания объекта (ведь для этого пришлось бы неким образом сериализовать его данные), а лишь от его адреса.

Если:

  • вам не нужно, чтоб объекты с одинаковым содержимым отвечали одной и той же ячейке словаря
  • не требуется, чтобы в разных сессиях работы программы словарь на тех же данных строился одинаковым
  • не пугает перспектива того, что вы объект удалили (и сам, и пару из словаря), потом новый создали, и он попадёт в ту же ячейку словаря (менеджер памяти переиспользует адрес),

то, похоже, всё должно быть нормально.

Если у вас объект содержит уникальные данные (например, полное имя пациента и его СНИЛС или что-то вроде), то вы можете перекрыть виртуальные методы GetHashCode и Equals для своего класса TReaction