Distinct() not calling equals methods

c#, observablecollection, silverlight, windows-phone, windows-phone-8

Solution

So you had the object that itself is being compared implement both `IEquatable` as well as `IEqualityComparer`. That generally doesn't make sense. `IEquatable` is a way of saying an object can compare itself to something else. `IEqualityComparer` is a way of saying it can compare two different things you give it to each other. You generally want to do one or the other, not both.

If you want to implement `IEquatable` then the object not only needs to have an `Equals` method of the appropriate signature, but it needs to override `GetHashCode` to have a sensible implementation for the given definition of equality. You didn't do that. You created `GetHashCode` method that takes an object as a parameter, but that's the overload used for `IEqualityComparer`. You need to override the parameter-less version when using `IEquatable` (the one defined in `Object`).

If you want to create a class that implements `IEqualityComparer` you need to pass the comparer to the `Distinct` method. Since you've defined the object as its own comparer you'd need to pass in some instance of this object as the second parameter. Of course, this doesn't really make a whole lot of sense this way; so it would be better, if you go this route, to pull out the two methods that go with `IEqualityComparer` into a new type, and create an instance of that type to the `Distinct` method. If you actually passed an object with those definitions in as a comparer, it'd work just fine.

Problem

I've implemented IEqualityComparer and IEquatable (both just to be sure), but when I call the Distinct() method on a collection it does not call the methods that come with it. Here is the code that I execute when calling Distinct(). ``` ObservableCollection<GigViewModel> distinctGigs = new ObservableCollection<GigViewModel>(Gigs.Distinct<GigViewModel>()); return distinctGigs; ``` I want to return an ObservableCollection that doesn't contain any double objects that are in the 'Gigs' ObservableCollection. I implement the interfaces like this on the GigViewModel class: ``` public class GigViewModel : INotifyPropertyChanged, IEqualityComparer<GigViewModel>, IEquatable<GigViewModel> { .... } ``` And override the methods that come with the interfaces like so: ``` public bool Equals(GigViewModel x, GigViewModel y) { if (x.Artiest.Naam == y.Artiest.Naam) { return true; } else { return false; } } public int GetHashCode(GigViewModel obj) { return obj.Artiest.Naam.GetHashCode(); } public bool Equals(GigViewModel other) { if (other.Artiest.Naam == this.Artiest.Naam) { return true; } else { return false; } } ``` Thanks for all the help I'm getting. So I've created a seperate class that implements IEqualityComparer and passed it's instance into the disctinct method. But the methods are still not being triggered. EqualityComparer: ``` class GigViewModelComparer : IEqualityComparer<GigViewModel> { public bool Equals(GigViewModel x, GigViewModel y) { if (x.Artiest.Naam == y.Artiest.Naam) { return true; } else { return false; } } public int GetHashCode(GigViewModel obj) { return obj.Artiest.Naam.GetHashCode(); } } ``` The `Distinct()` call: ``` GigViewModelComparer comp = new GigViewModelComparer(); ObservableCollection<GigViewModel> distinctGigs = new ObservableCollection<GigViewModel>(Gigs.Distinct(comp)); return distinctGigs; ``` EDIT2: The `GetHashCode()` method DOES get called! After implementing the new class. But the collection still contains duplicates. I have a list of 'Gigs' that contain an 'Artiest' (or Artist) object. This Artist has a Naam property which is a String (Name).

Original source