IEqualityComparer 和字符串
IEqualityComparer and string
为什么 IEqualityComparer
不能使用字符串?
type
TRec = record
s: string;
end;
var
rec1, rec2: TRec;
comparer: IEqualityComparer<TRec>;
res: boolean;
begin
rec1.s := 'a';
rec2.s := 'a';
comparer := TEqualityComparer<TRec>.default;
res := comparer.equals(rec1, rec2);
showMessage(boolToStr(res));
如果 TRec
条目包含数值或特定长度的字符串,则 IEqualityComparer
可以正常工作。如何使此代码有效?
编辑:
正如 Rudy Velthuis 在评论中注意到的那样,在新的 Delphi 版本中,相等 constant 字符串的结果为真,因为它们共享相同的内存并具有相同的地址(所以我之前关于更好的 RTTI 的假设是错误的。
对于复杂类型,相等性默认比较器仍然选择比较两个记录的原始字节的低级比较器 - 在我的示例的第二种情况下,相似字符串主体的不同地址。
如此可靠的方法是构造自己的比较器以处理复杂类型 - 请参阅下面的第三个示例。
type
TRecS = record
s: string;
end;
var
rec1, rec2: TRecS;
comparerS: IEqualityComparer<TRecS>;
cmp: IEqualityComparer<TRecS>;
res: boolean;
begin
rec1.s := 'const';
rec2.s := 'const';
comparerS := TEqualityComparer<TRecS>.default;
res := comparerS.equals(rec1, rec2);
Memo1.Lines.Add(boolToStr(res));
rec1.s := IntToStr(88);
rec2.s := IntToStr(88);
res := comparerS.equals(rec1, rec2);
Memo1.Lines.Add(boolToStr(res));
cmp := TEqualityComparer<TRecS>.Construct(
function(const Left, Right: TRecS): Boolean
begin
Result := Left.S = Right.S
end,
nil);
res := cmp.equals(rec1, rec2);
Memo1.Lines.Add(boolToStr(res));
-1 //denotes true
0
-1
为什么 IEqualityComparer
不能使用字符串?
type
TRec = record
s: string;
end;
var
rec1, rec2: TRec;
comparer: IEqualityComparer<TRec>;
res: boolean;
begin
rec1.s := 'a';
rec2.s := 'a';
comparer := TEqualityComparer<TRec>.default;
res := comparer.equals(rec1, rec2);
showMessage(boolToStr(res));
如果 TRec
条目包含数值或特定长度的字符串,则 IEqualityComparer
可以正常工作。如何使此代码有效?
编辑:
正如 Rudy Velthuis 在评论中注意到的那样,在新的 Delphi 版本中,相等 constant 字符串的结果为真,因为它们共享相同的内存并具有相同的地址(所以我之前关于更好的 RTTI 的假设是错误的。
对于复杂类型,相等性默认比较器仍然选择比较两个记录的原始字节的低级比较器 - 在我的示例的第二种情况下,相似字符串主体的不同地址。
如此可靠的方法是构造自己的比较器以处理复杂类型 - 请参阅下面的第三个示例。
type
TRecS = record
s: string;
end;
var
rec1, rec2: TRecS;
comparerS: IEqualityComparer<TRecS>;
cmp: IEqualityComparer<TRecS>;
res: boolean;
begin
rec1.s := 'const';
rec2.s := 'const';
comparerS := TEqualityComparer<TRecS>.default;
res := comparerS.equals(rec1, rec2);
Memo1.Lines.Add(boolToStr(res));
rec1.s := IntToStr(88);
rec2.s := IntToStr(88);
res := comparerS.equals(rec1, rec2);
Memo1.Lines.Add(boolToStr(res));
cmp := TEqualityComparer<TRecS>.Construct(
function(const Left, Right: TRecS): Boolean
begin
Result := Left.S = Right.S
end,
nil);
res := cmp.equals(rec1, rec2);
Memo1.Lines.Add(boolToStr(res));
-1 //denotes true
0
-1