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).
The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic. The Distinct<TSource> (IEnumerable<TSource>) method returns an unordered sequence that contains no duplicate values.
The java.lang.reflect.Method.equals (Object obj) method of Method class compares this Method Object against the specified object as parameter to equal (object obj) method. This method returns true if Method object is same as passed object.
The Distinct<TSource>(IEnumerable<TSource>) method returns an unordered sequence that contains no duplicate values. It uses the default equality comparer, Default, to compare values. In Visual Basic query expression syntax, a Distinct clause translates to an invocation of Distinct.
The Distinct<TSource> (IEnumerable<TSource>) method returns an unordered sequence that contains no duplicate values. It uses the default equality comparer, Default, to compare values. In Visual Basic query expression syntax, a Distinct clause translates to an invocation of Distinct.
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.
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