The default comparison tool for the instance reference variable compares the link, not the object. This way you get the object identifier, not the value identifier.
Thus, you need to provide your own comparison mapper if you want to enter a value identifier.
TestDict := TObjectDictionary<TTest, string>.Create(
[doOwnsKeys],
TEqualityComparer<TTest>.Construct(EqualityComparison, Hasher)
);
EqualityComparison, Hasher - . :
EqualityComparison :=
function(const Left, Right: TTest): Boolean
begin
Result := (Left.FId = Right.FId)
and (Left.FSecField = Right.FSecField)
and (Left.FThirdField = Right.FThirdField);
end;
Hasher :=
function(const Value: TTest): Integer
begin
Result := BobJenkinsHash(Value.FId, SizeOf(Value.FId), 0);
Result := BobJenkinsHash(Value.FSecField, SizeOf(Value.FSecField), Result);
Result := BobJenkinsHash(Value.FThirdField, SizeOf(Value.FThirdField), Result);
end;