HashSet(.NET4)不会忽略c#中的重复项

时间:2011-04-25 13:18:47

标签: c# .net-4.0 duplicates hashset

我已经读过.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可以与上一个对象具有相同的值。

但是如果我在最后检查哈希集,则会有重复的项目。 enter image description here

我添加的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的正确方法?提前感谢您的帮助。

5 个答案:

答案 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的构造函数中指定它。