문제

I was reading a book about Linq, and saw that the Distinct method has an overload that takes a comparer. This would be a good solution to a problem I have where I want to get the distinct entities from a collection, but want the comparison to be on the entity ID, even if the other properties are different.

According to the book, if I have a Gribulator entity, I should be able to create a comparer like this...

private class GribulatorComparer : IComparer<Gribulator> {
  public int Compare(Gribulator g1, Gribulator g2) {
    return g1.ID.CompareTo(g2.ID);
  }
}

...and then use it like this...

List<Gribulator> distinctGribulators
  = myGribulators.Distinct(new GribulatorComparer()).ToList();

However, this gives the following compiler errors...

'System.Collections.Generic.List' does not contain a definition for 'Distinct' and the best extension method overload 'System.Linq.Enumerable.Distinct(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEqualityComparer)' has some invalid arguments

Argument 2: cannot convert from 'LinqPlayground.Program.GribulatorComparer' to 'System.Collections.Generic.IEqualityComparer'

I've searched around a bit, and have seen plenty of examples that use code like this, but no complaints about compiler errors.

What am I doing wrong? Also, is this the best way of doing this? I want a one-off solution here, so don't want to start changing the code for the entity itself. I want the entity to remain as normal, but just in this one place, compare by ID only.

Thanks for any help.

도움이 되었습니까?

해결책

You're implementing your comparer as an IComparer<T>, the LINQ method overload requires an implementation of IEqualityComparer:

private class GribulatorComparer : IEqualityComparer<Gribulator> {
  public bool Equals(Gribulator g1, Gribulator g2) {
    return g1.ID == g2.ID;
  }
}

edit:

For clarification, the IComparer interface can be used for sorting, as that's basically what the Compare() method does.

Like this:

items.OrderBy(x => new ItemComparer());

private class ItemComparer : IComparer<Item>
{
    public int Compare(Item x, Item y)
    {
        return x.Id.CompareTo(y.Id)
    }
}

Which will sort your collection using that comparer, however LINQ provides a way to do that for simple fields (like an int Id).

items.OrderBy(x => x.Id);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top