I have a list which contains objects but these objests aren't unique in the list. I wrte this code to make unique them in another list:
foreach (CategoryProductsResult categoryProductsResult in categoryProductsResults.Where(categoryProductsResult => !resultSet.Contains(categoryProductsResult)))
{
resultSet.Add(categoryProductsResult);
}
But at the end resultSet is the same with categoryProductsResults.
categoryProductsResult's second row :
resultSet first row:
As you can see resultSet's first row and categoryProductsResult's second row is the same but it adds the second row to resultSet.
Do you have any suggestion?
Contains
uses the default comparer which is comparing references since your class does not override Equals
and GetHashCode
.
class CategoryProductsResult
{
public string Name { get; set; }
// ...
public override bool Equals(object obj)
{
if(obj == null)return false;
CategoryProductsResult other = obj as CategoryProductsResult;
if(other == null)return false;
return other.Name == this.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
Now you can simply use:
resultSet = categoryProductsResults.Distinct().ToList();
List uses the comparer returned by EqualityComparer.Default and according to the documentation for that:
The Default property checks whether type T implements the System.IEquatable(Of T) interface and, if so, returns an EqualityComparer(Of T) that uses that implementation. Otherwise, it returns an EqualityComparer(Of T) that uses the overrides of Object.Equals and Object.GetHashCode provided by T.
So you can either implement IEquatable on your custom class, or override the Equals (and GetHashCode) methods to do the comparison by the properties you require. Alternatively you could use linq:
bool contains = list.Any(i => i.Id == obj.Id);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With