【问题标题】:C# Hashset Contains Non-Unique ObjectsC# Hashset 包含非唯一对象
【发布时间】:2011-01-04 21:51:39
【问题描述】:

使用这个类

public class Foo
{
    public string c1, c2;

    public Foo(string one, string two)
    {
        c1 = one;
        c2 = two;
    }

    public override int GetHashCode()
    {
        return (c1 + c2).GetHashCode();
    }
}

还有这个哈希集

HashSet<Foo> aFoos = new HashSet<Foo>();
Foo aFoo = new Foo("a", "b");

aFoos.Add(aFoo);
aFoos.Add(new Foo("a", "b"));

label1.Text = aFoos.Count().ToString();

我得到了 2 的答案,当然它应该是 1。有没有办法解决这个问题,所以我的 HashSet 只包含唯一的对象?

谢谢,阿什。

【问题讨论】:

  • 你没有覆盖Equals

标签: c# hashset


【解决方案1】:

HashSet&lt;T&gt; 类型最终使用相等来确定 2 个对象是否相等。在 Foo 类型中,您只覆盖了 GetHashCode 而不是相等。这意味着相等检查将默认返回到使用引用相等的Object.Equals。这解释了为什么您会在 HashSet&lt;Foo&gt; 中看到多个项目。

要解决此问题,您需要覆盖 Foo 类型中的 Equals

public override bool Equals(object obj) { 
  var other = obj as Foo;
  if (other == null) {
    return false;
  }
  return c1 == other.c1 && c2 == other.c2;
}

【讨论】:

  • +1 因为它是正确的,但是可以补充一点,GetHashCode 返回的哈希值允许在不同的值下发生冲突,这就是为什么比较哈希码并不能确保对象相等的原因一般。
【解决方案2】:

您需要覆盖Equals 方法。只有GetHashCode是不够的。

【讨论】:

    【解决方案3】:

    您还需要重写 equals 方法。这样做的原因是允许哈希码碰撞两个不相等的对象。否则将无法正常工作。

    public override bool Equals(Object obj)
    { 
       Foo otherObject = obj as Foo;
       return otherObject != null && otherObject.c1 == this.c1 && otherObject.c2 == this.c2;
    }
    

    【讨论】:

    • 表达式local.Equals(null) 应该返回false 而不是true
    • 不错,只是为了给自己写的快:)。
    猜你喜欢
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-03
    • 2013-05-15
    相关资源
    最近更新 更多