简体   繁体   中英

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

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.

Following MSDN's advice , you'd be best off creating a separate class for your equality comparisons:

We recommend that you derive from the EqualityComparer class instead of implementing the IEqualityComparer interface, because the EqualityComparer class tests for equality using the IEquatable.Equals method instead of the Object.Equals method. This is consistent with the Contains, IndexOf, LastIndexOf, and Remove methods of the Dictionary class and other generic collections.

So, create a class, GigViewModelComparer , that derives from EqualityComparer and put your Equals and GetHashCode methods there.

Then, pass in an instance of that new comparer class in your call to Gigs.Distinct(new GigViewModelComparer()) and it should work. Follow along in the example in the MSDN link I provided above.

I've never seen somebody implement IEqualityComparer in the same class as the type of objects the collection in question contains, that is probably at least part of your problem.

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