【问题标题】:HashSet my class doesn't contain issueHashSet 我的课程不包含问题
【发布时间】:2012-04-14 16:29:38
【问题描述】:

我有一个类似的类:

public class Int16_2D
{
    public Int16 a, b;

    public override bool Equals(Object other)
    {
        return other is Int16_2D &&
        a == ((Int16_2D)other).a &&
        b == ((Int16_2D)other).b;
    }
}

这适用于HashSet<Int16_2D>。但是在Dictionary<Int16_2D, myType> 中,.ContainsKey 在不应该返回 false 时返回。我在== 的实现中遗漏了什么吗?

【问题讨论】:

标签: c# class hashmap equality hashset


【解决方案1】:

要让类在哈希表或字典中工作,您需要实现GetHashCode()!我不知道为什么它在 HashSet 中工作;我猜这只是运气。

请注意,使用可变字段来计算 Equals 或 GetHashCode() 是很危险的。为什么?考虑一下:

var x = new Int16_2D { a = 1, b = 2 };
var set = new HashSet<Int16_2D> { x };

var y = new Int16_2D { a = 1, b = 2 };
Console.WriteLine(set.Contains(y));   // True

x.a = 3;
Console.WriteLine(set.Contains(y));   // False
Console.WriteLine(set.Contains(x));   // Also false!

换句话说,当您设置x.a = 3; 时,您正在更改x 的哈希码。但是 x 在哈希表中的位置是基于它的 old 哈希码,所以 x 现在基本上丢失了。在http://ideone.com/QQw08查看此操作

另外,正如 svick 所说,实现 Equals 不会实现 ==。如果不实现==== 操作符会提供参考比较,所以:

var x = new Int16_2d { a = 1, b = 2 };
var y = new Int16_2d { a = 1, b = 2 };
Console.WriteLine(x.Equals(y));             //True
Console.WriteLine(x == y);                  //False

总之,最好将其设为不可变类型;由于它只有 4 个字节长,我可能会将其设为不可变结构。

【讨论】:

    【解决方案2】:

    您需要覆盖GetHashCode()。它与HashSet&lt;T&gt; 一起工作的事实可能只是一个幸运的巧合。

    这两个集合都使用从GetHashCode 获得的哈希码来查找应该放置对象的存储桶(即对象列表)。然后它搜索该存储桶以找到对象,并使用Equals 来确保相等。这就是 Dictionary 和 HashSet 的快速查找属性。但是,这也意味着,如果 GetHashCode 没有被覆盖以使其对应于类型 Equals 方法,您将无法在其中一个集合中找到这样的对象。

    您应该几乎总是同时实现GetHashCodeEquals,或者一个都不实现。

    【讨论】:

      【解决方案3】:

      您还需要覆盖 GetHashCode 才能使字典正常工作。

      【讨论】:

        【解决方案4】:

        您还必须覆盖 GetHashCode() - 这与覆盖 Equals 密切相关。 Dictionary 使用GetHashCode() 来确定一个值将落入哪个 bin - 只有在该 bin 中找到合适的项目时,它才会检查项目的实际相等性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-03
          • 1970-01-01
          • 1970-01-01
          • 2021-10-29
          • 1970-01-01
          • 1970-01-01
          • 2014-07-11
          • 1970-01-01
          相关资源
          最近更新 更多