目前我的hashsets有问题。我有不可变的类,只包含一个项目,当我将两个不同的类添加到相同的数据到一个哈希集时,我在集合中得到它们。这很奇怪,因为我在基类和超类上都重载了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();
}
如您所见,所有实际工作都推迟到了BigInteger,即id。这是一个.net类,如果我只是将BigInteger添加到一个hashset,我已经确认我不会重复。
澄清:
BigInteger a;
HashSet<Contact> set;
set.add(new KeyOnlyContact(a));
set.add(new KeyOnlyContact(a));
set.Count == 2
答案 0 :(得分:10)
public abstract int GetHashCode();
您不小心重新声明了GetHashCode
(方法隐藏)。删除此声明,它可能会开始工作。当您的派生归类为override GetHashCode
时,他们会提供此版本 - 他们不会覆盖object.GetHashCode
,这就是所需要的。
如果你想要一个抽象的GetHashCode
,或许:
public sealed override int GetHashCode() { return GetHashCodeImpl(); }
protected abstract int GetHashCodeImpl();
现在,派生类型必须提供GetHashCodeImpl
,并且它们都映射到object.GetHashCode
。