此声明是否正确:TDictionary <TPair <int32,int64>,bool> [重复]

我声明这个对象

MyDict := TDictionary<TPair<int32, int64>, bool>.create([]);
MyDict.add(TPair<Int32, Int64>.create(2, 0), true);

为什么

MyDict.TryGetValue(TPair<int32, int64>.create(2, 0), result)

找不到我刚刚添加的上一个密钥?

评论
  • raut
    raut 回复

    The problem is that the default equality comparer for TPair<TKey,TValue> tests naive binary equality for the record. In your case the record specialises as:

    TPair<int32,int64> = record
      Key: int32;
      Value: int64;
    end;
    

    Because the record is aligned, there is padding. There are four bytes of padding between Key and Value. The values of this padding is then used by the default comparer.

    If you could define your own type, instead of using TPair<TKey,TValue> then you could declare it packed. That will be fine for simple value types as you use here for TKey and TValue, but more complex non-value types then even that would fail.

    The other approach is to define your own equality comparer, and pass it to the dictionary constructor. You can do this by calling TEqualityComparer<TPair<TKey,TValue>>.Contruct() passing an equality comparison function and a hasher function. See this question for an example: What is the canonical way to write a hasher function for TEqualityComparer.Construct?