【问题标题】:Duplicate elements in a hashset哈希集中的重复元素
【发布时间】:2010-04-29 21:39:52
【问题描述】:

我现在对哈希集有疑问。我有不可变的类并且只包含一个项目,当我将两个具有相同数据的不同类添加到哈希集中时,我会将它们都放在集合中。这很奇怪,因为我在基类和超类上都重载了 Equals 和 GetHashCode。

public abstract class Contact :IEquatable<Contact>
{
    public readonly BigInteger Id;

    public Contact(BigInteger id) { this.Id = id; }

    public abstract bool Equals(Contact other);

    public abstract int GetHashCode();

    public abstract bool Equals(object obj);
}

以及继承类:

public class KeyOnlyContact :Contact, IEquatable<KeyOnlyContact>
{
    public KeyOnlyContact(BigInteger id) :base(id) { }

    public override bool Equals(object obj)
    {
        if (obj is KeyOnlyContact)
            return Equals(obj as KeyOnlyContact);
        else if (obj is Contact)
            return Equals(obj as Contact);
        else
            return (this as object).Equals(obj);
    }

    public override bool Equals(Contact other)
    {
        if (other is KeyOnlyContact)
            return Equals(other as KeyOnlyContact);
        else
            return (this as object).Equals(other as object);
    }

    public bool Equals(KeyOnlyContact other)
    {
        return other.Id.Equals(Id);
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

如您所见,所有实际工作都被推迟到作为 id 的 BigInteger 上。这是一个 .net 类,我已经确认如果我只是将 BigInteger 添加到哈希集中,我不会得到重复。

澄清一下:

BigInteger a;
HashSet<Contact> set;

set.add(new KeyOnlyContact(a));
set.add(new KeyOnlyContact(a));

set.Count == 2

【问题讨论】:

  • 顺便说一句,打开警告,您应该会看到:“警告 [n] 'Foo.GetHashCode()' 隐藏继承的成员 'object.GetHashCode()'。要使当前成员覆盖该实现, 添加覆盖关键字。否则添加新关键字。”
  • 我收到了警告,不幸的是,我也收到了关于未注释公共方法的警告,这是一项持续的任务,它不断地将有用的警告隐藏在烦人的文档警告中。我想我可能会改变那个选项!

标签: c# .net debugging hashset


【解决方案1】:
public abstract int GetHashCode();

你不小心重新声明了GetHashCode(隐藏方法)。删除此声明,它可能会开始工作。当您的派生类为 override GetHashCode 时,它们提供 版本 - 它们不会覆盖 object.GetHashCode,这是必需的。

如果你想要一个摘要GetHashCode,也许:

public sealed override int GetHashCode() { return GetHashCodeImpl(); }
protected abstract int GetHashCodeImpl();

现在派生类型必须提供GetHashCodeImpl,并且都映射到object.GetHashCode

【讨论】:

  • 呸,这隐藏了方法,而不是要求继承类自己实现它。我去看看能不能解决
  • 是的。这就是我早上在火车上的愚蠢时间编码所得到的:(非常感谢 Marc
  • 我不能说 public override abstract int GetHashCode();修复它并要求覆盖类提供自己的哈希码?
  • @Martin - 你知道吗 - 我从没想过要尝试,它似乎工作正常。好节目!
  • 哇:哦,我期待你回来的理由看起来不错,但实际上是一个糟糕的主意;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多