Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashSet (.NET4) isn't ignoring duplicates in c# [duplicate]

I've read that a HashSet in .net4 will ignore all the duplicates. So what I do is:

    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 can have the same values as the previous object.

But if I check the hashset later in the end, there are duplicate items. enter image description here

the equals and gethashcode method i added but didn't help. I also added an id to the class. So 2 objects can have the same content but different 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;
    }

So my question now is: What am I doing wrong, or is this not the right way to use a HashSet? Thanks in advance for any help.

like image 936
Olivier_s_j Avatar asked Dec 06 '22 22:12

Olivier_s_j


2 Answers

It will depend on the implementations of GetHashCode() and Equals() on the medbaseid class.

See http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx for more info.

By default objects will only compare as equal if they are literally the same object. Having the same "content" is not sufficient to make them equal. If you want two different objects with the same "content" to be equal, you must override Equals() to implement that logic. Whenever you override Equals() you must also override GetHashCode() for them to work correctly inside a hashing data structure like HashSet<>.

like image 58
Daniel Renshaw Avatar answered Jan 17 '23 04:01

Daniel Renshaw


For Hashset<medbaseid> to work properly, either medbaseid must be a struct or you have to define a field based equality on your class medbaseid by overriding Equals() and GetHashCode(). Alternatively you can pass in a custom IEqualityComparer when you create the Hashet.

like image 28
BrokenGlass Avatar answered Jan 17 '23 05:01

BrokenGlass