开发者

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

开发者 https://www.devze.com 2023-02-28 07:42 出处:网络
This question already has answers here: C# Hashset Contains Non-Unique Objects (3 answers) Closed 9 years ago.
This question already has answers here: C# Hashset Contains Non-Unique Objects (3 answers) Closed 9 years ago.

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_typ开发者_Python百科e_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.

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

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.


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<>.


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.


Did you override GetHashCode (and Equals)? In the standard implementation, different objects have different hashcodes, even if all the properties are equal.


Sounds like you need to implement GetHashCode and equality members. Eric Lippert has an excellent post on this subject.


Bear in mind that equality is in the eye of the beholder. Specifically, in order to be considered equal, two objects must possess the same hash code as returned by GetHashCode and must return true for Equals (two virtual/overridable methods found on the object base class).

In the case of a HashSet, you can also specify a custom equality comparer in the constructor that performs equality comparison and hash code generation.

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

Point being, the likely cause for your problem is that your medbaseids...although equal in the values of their members, are not actually equal by hash code and Equals. The default behavior for Equals and hash code is based on object reference equality (actually the same instance of the object).

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

0

精彩评论

暂无评论...
验证码 换一张
取 消