HashSet (.NET4) does not ignore duplicates in C #

I read that HashSet in .net4 will ignore all duplicates. So what I do:

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 at the end, there are duplicate elements. enter image description here

equals and gethashcode method, which I added but didn’t help. I also added id to the class. Thus, 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 now my question is: what am I doing wrong, or is this the wrong way to use a HashSet ? Thanks in advance for any help.

+4
source share
5 answers

This will depend on the implementation of GetHashCode() and Equals() on the medbaseid class.

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

By default, objects will only be compared as equal if they are literally the same object. Having the same β€œcontent” is not enough to make them equal. If you want two different objects with the same β€œcontents” to be equal, you must override Equals() to implement this logic. Whenever you override Equals() , you must also override GetHashCode() so that they work correctly inside the hash data structure, such as HashSet<> .

+11
source

For the Hashset<medbaseid> to work correctly, either medbaseid must be struct , or you need to define equality by field on your medbaseid class by overriding Equals() and GetHashCode() . Alternatively, you can switch to custom IEqualityComparer when you create the Hash .

+1
source

Have you redefined GetHashCode (and Equals )? In the standard implementation, different objects have different hash codes, even if all properties are equal.

+1
source

It looks like you need to implement GetHashCode and equality members. Eric Lippert has a great post on this.

+1
source

Keep in mind that equality is in the eye of the beholder. In particular, in order to be considered equal, two objects must have the same hash code returned by GetHashCode, and must return true for Equals (two virtual / redefined methods found in the base class of the object).

In the case of a HashSet, you can also specify your own comparison comparator in the constructor, which performs equality comparison and hash code generation.

http://msdn.microsoft.com/en-us/library/bb359100.aspx

The point, the probable cause for your problem is that your medbaseids ... although it is equal to the values ​​of its members, is not really equal to the hash code and Equals. The default behavior for Equals and the hash code is based on the equality of object references (in fact, the same instance of the object).

Override Equals and GetHashCode on medbaseid . Or define an IEqualityComparer<medbaseid> that performs the comparison and will specify it in the constructor for your HashSet.

+1
source

All Articles