Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distinct() not calling equals methods

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

like image 709
Tim Kranen Avatar asked Jan 07 '14 14:01

Tim Kranen


People also ask

When is the query represented by distinct<tsource> method not executed?

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.

What is the use of method equals in Java?

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.

What is the use of distinct in VB NET?

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.

What is the use of distinct in IEnumerable?

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.


1 Answers

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.

like image 155
Servy Avatar answered Sep 28 '22 09:09

Servy