delphi Using records as key in TDictionary

会有一股神秘感。 提交于 2019-12-03 11:39:36

问题


Can you use a record as a Key value in TDictionary? I want to find objects based on combination of string, integer and integer.

TUserParKey=record
  App:string;
  ID:integer;
  Nr:integer;
end;

...

var
  tmpKey:TUserParKey;
  tmpObject:TObject;
begin
  tmpObject:= TTObject.Create(1); 
  tmpKey.App:='1';
  tmpKey.ID :=1;
  tmpKey.Nr :=1;

  DTUserPars.Add(tmpKey,tmpObject)

...

var
  tmpKey:TUserParKey;
begin
  tmpKey.App:='1';
  tmpKey.ID :=1;
  tmpKey.Nr :=1;

  if not DTUserPars.TryGetValue(tmpKey,Result) then begin
    result := TTObject.Create(2); 
  end;

This returns object 2.


回答1:


Yes, you can use records as keys in a TDictionary but you should provide your own IEqualityComparer when creating the dictionary because the default one for records just does a dumb binary compare of the record. This fails for a record containing a string because it just compares the pointer of that string which may be different even if the string contains the same value.

Such a comparer would look like this:

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

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;



回答2:


My best approach should be to joint the default hash code of the base types.

For instance:

Value.App.GetHashCode + Value.ID.GetHashCode + Value.Nr.GetHashCode;


来源:https://stackoverflow.com/questions/27820171/delphi-using-records-as-key-in-tdictionary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!