Как использовать пользовательский компаратор с методом Linq Distinct?

Я читал книгу о Linq и увидел, что метод Distinct имеет перегрузку, которая требует компаратора. Это было бы хорошим решением проблемы, в которой я хочу получить различные сущности из коллекции, но хочу, чтобы сравнение было на идентификаторе сущности, даже если другие свойства отличаются.

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

...а затем использовать его как этот...

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

однако, это дает следующие ошибки компилятора...

'.Коллекции.Родовой.Список "не содержит определения для системы "Distinct"и" Best extension method overload".В LINQ.Перечислимый.Distinct (System.Коллекции.Родовой.IEnumerable, System.Коллекции.Родовой.IEqualityComparer) ' имеет некоторые недопустимые аргументы

Аргумент 2: не удается преобразовать из ' LinqPlayground.Программа.GribulatorComparer в - Система.Коллекции.Родовой.Компаратор IEqualityComparer'

Я немного поискал и видел много примеров, которые используют такой код, но никаких жалоб на ошибки компилятора.

что я делаю не так? Кроме того, это лучший способ сделать это? Я хочу одноразовое решение здесь, поэтому не хочу начинать изменять код для самой сущности. Я хочу, чтобы сущность оставалась нормальной, но только в этом месте, сравните только по ID.

Спасибо за любую помощь.

1 ответов


вы реализуете свой компаратор как IComparer<T>, перегрузка метода LINQ требует реализации IEqualityComparer:

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

edit:

уточнение IComparer интерфейс может использоваться для сортировки, так как это в основном то, что Compare() метод.

такой:

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

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

который будет сортировать вашу коллекцию с помощью этого компаратора, однако LINQ предоставляет способ сделать это для простых полей (например, int Id).

items.OrderBy(x => x.Id);