Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Использование записей в качестве ключа в TDictionary и корректная реализация

Delphi , Компоненты и Классы , Коллекции

Заголовок: Использование записей в качестве ключа в TDictionary и корректная реализация

В процессе программирования на Delphi часто возникает необходимость использовать Record как ключ в TDictionary. Однако, по умолчанию, TDictionary использует сравнение записей на основе бинарного сравнения, что может привести к некорректным результатам, особенно в случае Record, содержащего строковые поля.

Проблема заключается в том, что бинарное сравнение записей сравнивает указатели на строковые поля, что может отличаться даже если строковые значения совпадают. Чтобы решить эту проблему, необходимо предоставить собственный IEqualityComparer при создании TDictionary, который будет корректно сравнивать Record в качестве ключа.

Ниже представлен пример реализации IEqualityComparer для Record, содержащего строковое поле, целое число и еще одно целое число:

type
  TUserParKey = record
    App: string;
    ID: Integer;
    Nr: Integer;
  end;

  TUserParKeyComparer = class(TEqualityComparer<TUserParKey>)
  private
    function Equals(const Left, Right: TUserParKey): Boolean; override;
    function GetHashCode(const Value: TUserParKey): Integer; override;
  end;

implementation

function TUserParKeyComparer.Equals(const Left, Right: TUserParKey): Boolean;
begin
  Result := (Left.App = Right.App) and (Left.ID = Right.ID) and (Left.Nr = Right.Nr);
end;

function TUserParKeyComparer.GetHashCode(const Value: TUserParKey): Integer;
begin
  Result := BobJenkinsHash(PChar(Value.App)^, Length(Value.App) * SizeOf(Char), 0);
  Result := BobJenkinsHash(Value.ID, SizeOf(Integer), Result);
  Result := BobJenkinsHash(Value.Nr, SizeOf(Integer), Result);
end;

var
  DTUserPars: TDictionary<TUserParKey, TObject>;
  tmpKey: TUserParKey;
  tmpObject: TObject;

begin
  DTUserPars := TDictionary<TUserParKey, TObject>.Create(TUserParKeyComparer);
  tmpObject := TObject.Create(1);
  tmpKey.App := '1';
  tmpKey.ID := 1;
  tmpKey.Nr := 1;
  DTUserPars.Add(tmpKey, tmpObject);

  tmpKey.App := '1';
  tmpKey.ID := 1;
  tmpKey.Nr := 1;
  if not DTUserPars.TryGetValue(tmpKey, Result) then
    Result := TObject.Create(2);
end;

В данном примере мы создаем собственный TUserParKeyComparer, который реализует интерфейс IEqualityComparer для Record TUserParKey. В методе Equals мы сравниваем поля App, ID и Nr на равенство, а в методе GetHashCode мы используем функцию BobJenkinsHash для вычисления хеш-кода на основе значений этих полей.

При создании TDictionary мы передаем созданный TUserParKeyComparer, что гарантирует корректное сравнение Record в качестве ключа.

Альтернативным подходом может быть использование строки, состоящей из сериализованного Record в качестве ключа. В этом случае можно воспользоваться библиотекой, такой как SuperObject, для сериализации Record. Однако, этот подход может потребовать больше памяти и времени, чем использование собственного IEqualityComparer.

В заключение, при использовании Record в качестве ключа в TDictionary важно предоставить корректную реализацию IEqualityComparer, чтобы гарантировать правильное сравнение записей. В противном случае, результаты работы TDictionary могут быть некорректными.

Создано по материалам из источника по ссылке.

В контексте данного текста рассматривается проблема использования записей в качестве ключа в TDictionary в Delphi и необходимость корректной реализации IEqualityComparer для сравнения записей, содержащих строковые поля. Автор приводит пример реализации IE


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Коллекции ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:58:00/0.0055150985717773/1