Delphi 如何在敏感的TechQualityComparer for TDictionary中创建案例?

Delphi 如何在敏感的TechQualityComparer for TDictionary中创建案例?,delphi,Delphi,我有一个使用t词典的案例: var D: TDictionary<string, integer>; begin D := TDictionary<string, integer>.Create(TCustomEqualityComparer.Create()); try D.Add('One', 1); D.Add('Two', 2); D.Add('Three', 3); showmessage(inttostr(D.Item

我有一个使用t词典的案例:

var D: TDictionary<string, integer>;
begin
  D := TDictionary<string, integer>.Create(TCustomEqualityComparer.Create());
  try
    D.Add('One', 1);
    D.Add('Two', 2);
    D.Add('Three', 3);

    showmessage(inttostr(D.Items['One']));
    showmessage(inttostr(D.Items['TWO']));
  finally
    D.Free;
  end;
end;
但是,我得到一个“未找到项”异常。我使用的是Delphi2010版本14.0.3513.24210


有人知道我的代码怎么了吗?

对于返回等于true的所有值,哈希代码必须相同!在发送给HashFunction之前,请尝试在GetHashCode中使用大写值。

谢谢。我已经更改了TCustomEqualityComparer.GetHashCode,它可以按照您所说的那样工作:

function TCustomEqualityComparer.Equals(const Left, Right: string): Boolean;
begin
  {$IFDEF UNICODE }
    Result := (Left.ToUpper = Right.ToUpper);
  {$ELSE }
    Result := SameText(Left, Right);
  {$ENDIF }
end;

function TCustomEqualityComparer.GetHashCode(const Value: string): Integer;
var s: string;
begin
  s := {$IFDEF UNICODE } Value.ToUpper {$ELSE } UpperCase(Value) {$ENDIF };
  Result := BobJenkinsHash(s[1], Length(s) * SizeOf(s[1]), 0);
end;
使用System.Generics.Collections、System.Generics.Default;
变量
D:词典;
开始
D:=TDictionary.Create(TIStringComparer.Ordinal);//这就是诀窍
尝试
D.添加(“一”,1);
.
.
最后
D.免费;
结束;
结束;

您确定原始Equals已经不区分大小写了吗?这是在unit-Generics.Defaults.pas中定义的原始Equals方法:函数Equals_-UString(Inst:PSimpleInstance;const-Left,Right:unicode-destring):Boolean;开始结果:=左=右;结束;你是对的!我混淆了原始实现和示例。UpperCase/SameText仅适用于ASCII文本(它只处理'a'…'z')。在Delphi的UNICODE版本中使用.ToUpper。代码片段更新了…我知道这是一个旧答案,但我认为它提供了与问题相反的答案。根据System.Generics.Defaults.TIStringComparer.Ordinal的帮助文件,它“返回一个执行区分大小写字符串比较的TStringComparer对象。”,而不是不区分大小写的。@AdamG-这一定是文档中的一个错误,我刚刚测试了它,它进行了区分大小写的比较。这也解释了InsensitiveStringComparer类名中的I。
D.Items['TWO']
function TCustomEqualityComparer.Equals(const Left, Right: string): Boolean;
begin
  {$IFDEF UNICODE }
    Result := (Left.ToUpper = Right.ToUpper);
  {$ELSE }
    Result := SameText(Left, Right);
  {$ENDIF }
end;

function TCustomEqualityComparer.GetHashCode(const Value: string): Integer;
var s: string;
begin
  s := {$IFDEF UNICODE } Value.ToUpper {$ELSE } UpperCase(Value) {$ENDIF };
  Result := BobJenkinsHash(s[1], Length(s) * SizeOf(s[1]), 0);
end;
uses System.Generics.Collections, System.Generics.Defaults;

var
  D: TDictionary<string, Integer>;
begin
  D := TDictionary<string, Integer>.Create(TIStringComparer.Ordinal); // ‹- this is the trick
  try
    D.Add('One', 1);
    .
    .
  finally
    D.Free;
  end;
end;