我已经读过.net4中的HashSet将忽略所有重复项。所以我所做的是:
HashSet<medbaseid> medbaseidlist = new HashSet<medbaseid>();
for (int i = 2; i <= rowCount; i++)
{
medbaseid medbaseid = new medbaseid() {
mainClass = xlRange.Cells[i, 1].Value2.ToString(),
genName = xlRange.Cells[i, 2].Value2.ToString(),
speciality = xlRange.Cells[i, 3].Value2.ToString(),
med_type_id = getId(xlRange.Cells[i, 4].Value2.ToString(),
id = i-1
)
};
medbaseidlist.Add(medbaseid);
}
medbaseid
可以与上一个对象具有相同的值。
但是如果我在最后检查哈希集,则会有重复的项目。
我添加的equals和gethashcode方法但没有帮助。我还在课堂上添加了一个id。因此,2个对象可以具有相同的内容,但ID不同:
public override bool Equals(object obj)
{
medbaseid medb = (medbaseid)obj;
return ((medb.id == this.id) && (medb.genName == this.genName) && (medb.mainClass == this.mainClass) && (medb.med_type_id == this.med_type_id) && (medb.speciality == this.speciality)) ? true : false;
}
public override int GetHashCode()
{
return id;
}
所以现在我的问题是:我做错了什么,或者这不是使用HashSet
的正确方法?提前感谢您的帮助。
答案 0 :(得分:11)
这将取决于GetHashCode()
类Equals()
和medbaseid
的实施。
有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx。
默认情况下,如果对象实际上是同一个对象,则它们只会相等。拥有相同的“内容”并不足以使它们相等。如果您希望具有相同“内容”的两个不同对象相等,则必须覆盖Equals()
以实现该逻辑。每当您覆盖Equals()
时,您还必须覆盖GetHashCode()
,才能在HashSet<>
等散列数据结构中正常工作。
答案 1 :(得分:1)
要使Hashset<medbaseid>
正常工作,medbaseid
必须是struct
,或者您必须通过覆盖medbaseid
在您的班级Equals()
上定义基于字段的相等性}和GetHashCode()
。或者,您可以在create the Hashet时传递自定义IEqualityComparer
。
答案 2 :(得分:1)
您是否覆盖了GetHashCode
(以及Equals
)?在标准实现中,不同的对象具有不同的哈希码,即使所有属性都相同。
答案 3 :(得分:1)
听起来你需要实现GetHashCode
和平等成员。 Eric Lippert在这个问题上有一个excellent post。
答案 4 :(得分:1)
请记住,平等是旁观者的眼睛。具体来说,为了被认为是相同的,两个对象必须具有与GetHashCode返回的相同的哈希码,并且必须为Equals返回true(在对象基类上找到两个虚拟/可覆盖的方法)。
对于HashSet,您还可以在构造函数中指定自定义相等比较器,以执行相等比较和哈希码生成。
http://msdn.microsoft.com/en-us/library/bb359100.aspx
指出,问题的可能原因是你的medbaseids
...虽然其成员的值相等,但实际上并不等于哈希码和等号。 Equals和hash代码的默认行为基于对象引用相等(实际上是对象的相同实例)。
在medbaseid
上覆盖Equals和GetHashCode。或者定义进行比较的IEqualityComparer<medbaseid>
并在HashSet的构造函数中指定它。