【问题标题】:C# SortedDictionary ContainsKey returns false even though key exists即使键存在,C# SortedDictionary ContainsKey 也会返回 false
【发布时间】:2016-06-07 18:22:56
【问题描述】:

这就是我创建 SortedDictionary 的方式:

protected class OccupiedComparer : IComparer<Structure>
{
    public int Compare(Structure a, Structure b)
    {
        if (a == b)
            return 0;

        if (a.AtomicPosition.x > b.AtomicPosition.x)
            return 1;
        else
            return -1;
    }
}

protected SortedDictionary<Structure, Vector2> m_BuildingOccupied = new SortedDictionary<Structure, Vector2>(new OccupiedComparer());

我运行这段代码:

m_BuildingOccupied.Add(s, new Vector2(x, y));
foreach (var k in m_BuildingOccupied.Keys) {
    bool c = m_BuildingOccupied.ContainsKey(k);
    int hs = k.GetHashCode();
    Debug.Log(hs + ", " + c);
}

即使所有添加的键都打印到控制台,但其中一些键的“c”等于 false,这意味着 ContainsKey 返回 false。即使键显然存在于字典中。

知道导致此问题的原因是什么吗?也许是我的自定义比较器?

【问题讨论】:

  • 您的比较器正在混合引用相等和值相等。特别是如果您有两个具有相同AtomicPosition.x 值的Structure 对象,则它们不会被视为相等。这很糟糕,因为 Compare(a,b)Compare(b,a) 都会返回 -1。
  • 怎么回事?我这样做:如果(a == b)返回 0,所以如果两个对象相同,甚至在查看原子位置之前它应该返回 0
  • 因为a == b 正在进行参考比较(除非您实际上已经为Structure 加载了== 运算符)。看来您的比较器应该只是 return a.AtomicPosition.x.CompareTo(b.AtomicPosition.x);
  • 为什么不在比较中为未找到的键之一添加条件断点并查看它的作用?
  • @kamac a == b 如果它们只是相同的对象,而不是如果它们具有相同的AtomicPosition.x。因此,当字典尝试对具有相同AtomicPosition.x 的两个不同Structure 对象进行排序时,即使您交换它们,它也会始终认为第一个小于第二个。基本上你会有 a

标签: c# dictionary unity3d


【解决方案1】:

默认运算符 == 比较类的引用

解决方案:

重载 Equals 和 GetHashcode() 或改为比较所有字段。

【讨论】:

  • a == ba.Equals(b) 将是相同的,除非 ==Structure 重载或 EqualsStructure 覆盖,如果两者都是,那么它们可能仍然会给出结果相同。
  • 不,对于 structres 它们的操作方式不同,Equals 会比较对象的所有字段 == isnt
  • @Dr.Haimovitz Structure 是一个类,它只命名为 Structure
  • 啊不知道,抱歉
  • @Dr.Haimovitz 因为它是一个代表建筑物、火炬或任何“结构”的类
猜你喜欢
  • 2015-09-11
  • 1970-01-01
  • 2015-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 2021-07-06
相关资源
最近更新 更多