J..*_*... 7 delphi generics hash dictionary delphi-xe2
这再现了问题:
program Project1;
{$APPTYPE CONSOLE}
uses
Generics.Collections;
type
TStringRec = record
s1 : string;
s2 : string;
end;
TGetHash<TKey,TValue> = class(TEnumerable<TPair<TKey,TValue>>)
public
type
TItem = record
HashCode: Integer;
Key: TKey;
Value: TValue;
end;
TItemArray = array of TItem;
public
FItems: TItemArray;
end;
var
LCrossRef : TDictionary<TStringRec, integer>;
LRec : TStringRec;
i : integer;
begin
LCrossRef := TDictionary<TStringRec, integer>.Create();
LRec.s1 := 'test1';
LRec.s2 := 'test2';
LCrossRef.Add(LRec, 1);
LRec.s1 := 'test1';
LRec.s2 := 'test2';
if LCrossRef.TryGetValue(LRec, i) then begin
writeln('ok');
end else begin
LCrossRef.Add(LRec, 1);
for i := Low(TGetHash<TStringRec, integer>
(LCrossRef).FItems)
to High(TGetHash<TStringRec, integer>
(LCrossRef).FItems) do
WriteLn(TGetHash<TStringRec, integer>(LCrossRef).FItems[i].HashCode);
WriteLn('not ok');
end;
ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)
字典无法检索项目并HashCode为包含相同字符串的记录生成不同的字段.
这部分在QC-#122791中注明,但使用打包记录的解决方法不适用于字符串记录(至少上述示例在TStringRec声明为时也失败packed record).
这有一个明智的解决方法吗?
我目前的策略是连接原本会进入记录并使用其他字符串的字符串TDictionary<string, TValue>,但这自然不令人满意.
这是已知的限制,即设计上的限制.记录的默认比较器和缓冲区仅适用于纯值类型记录,以及没有填充的记录.
设计人员可以选择使用RTTI来比较/散列记录.但是,他们选择不这样做.这种选择的一些明显合理的原因是:
处理此问题的方法是在使用通用集合时提供自己的比较器和哈希.
您当前连接字符串的策略不起作用.考虑'a'和'aa',然后'aa'和'a'.要使用基于文本的方法,您需要将记录序列化为JSON.
| 归档时间: |
|
| 查看次数: |
1208 次 |
| 最近记录: |