delphi在TDictionary中使用记录作为键 [英] delphi Using records as key in TDictionary

查看:395
本文介绍了delphi在TDictionary中使用记录作为键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以将记录用作TDictionary中的键值吗?我想根据字符串,整数和整数的组合找到对象。

  TUserParKey = record 
App:string;
ID:整数;
Nr:integer;
结尾;

...

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

DTUserPars.Add(tmpKey,tmpObject)

...

  var 
tmpKey:TUserParKey;
开始
tmpKey.App:=1;
tmpKey.ID:= 1;
tmpKey.Nr:= 1;

如果不是DTUserPars.TryGetValue(tmpKey,Result),则开始
结果:= TTObject.Create(2);
结尾;

这将返回对象2。

是,您可以将记录用作TDictionary中的键,但是在创建字典时,您应该提供自己的IEqualityComparer,因为记录的默认记录只是对记录进行愚蠢的二进制比较。
对于包含字符串的记录,此操作失败,因为它只是比较该字符串的指针,即使该字符串包含相同的值,该指针也可能会有所不同。



如此比较器如下所示:

  type 
TUserParKeyComparer = class(TEqualityComparer< TUserParKey>)
函数Equals(const Left,Right:TUserParKey):布尔值;覆盖
函数GetHashCode(const Value:TUserParKey):整数;覆盖
结尾;

函数TUserParKeyComparer.Equals(const Left,Right:TUserParKey):布尔值;
开始
结果:=(Left.App = Right.App)和(Left.ID = Right.ID)和(Left.Nr = Right.Nr);
结尾;

函数TUserParKeyComparer.GetHashCode(const Value:TUserParKey):整数;
begin
结果:= BobJenkinsHash(PChar(Value.App)^,Length(Value.App)* SizeOf(Char),0);
结果:= BobJenkinsHash(Value.ID,SizeOf(Integer),Result);
结果:= BobJenkinsHash(Value.Nr,SizeOf(Integer),Result);
结尾;


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.

解决方案

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;

这篇关于delphi在TDictionary中使用记录作为键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆