简体   繁体   中英

Linq Distinct not returning expected values

I am trying to get a list of distinct items from a custom collection, however the comparison seems to be getting ignored as I keep getting duplicates appearing in my list. I have debugged the code and I can clearly see that the values in the list that I am comparing are equal...

NOTE: The Id and Id2 values are strings

Custom Comparer:

public class UpsellSimpleComparer : IEqualityComparer<UpsellProduct>
{
    public bool Equals(UpsellProduct x, UpsellProduct y)
    {
        return x.Id == y.Id && x.Id2 == y.Id2;
    }

    public int GetHashCode(UpsellProduct obj)
    {
        return obj.GetHashCode();
    }
}

Calling code:

var upsellProducts = (Settings.SelectedSeatingPageGuids.Contains(CurrentItem.ID.ToString())) ?
                              GetAOSUpsellProducts(selectedProductIds) : GetGeneralUpsellProducts(selectedProductIds);

// we use a special comparer here so that same items are not included
var comparer = new UpsellSimpleComparer();
return upsellProducts.Distinct(comparer);

Most likely UpsellProduct has default implementation of GetHashCode that returns unique value for each instance of reference type.

To fix - either implement one correctly in UpsellProduct or in comparer.

public class UpsellSimpleComparer : IEqualityComparer<UpsellProduct>
{
   public bool Equals(UpsellProduct x, UpsellProduct y)
   {
       return x.Id == y.Id && x.Id2 == y.Id2;
   }

   // sample, correct GetHashCode is a bit more complex
   public int GetHashCode(UpsellProduct obj)
   {
      return obj.Id.GetHashCode() ^ obj.Id2.GetHashCode();
   }

}

Note for better code to compute combined GetHashCode check Concise way to combine field hashcodes? and Is it possible to combine hash codes for private members to generate a new hash code?

Your GetHashCode() doesn't return the same values even two UpsellProduct instances are consider equals by your Equals() method.

Use something like this to reflect the same logic instead.

public int GetHashCode(UpsellProduct obj)
{
    return obj.Id.GetHashCode() ^ obj.Id2.GetHashCode();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM