Список <T>.Distinct () в C# - несколько критериев EqualityComparer?

У меня есть набор объектов, которые имеют несколько свойств в каждом из них. Я часто должен получать список отличных значений для многих свойств в этом наборе. Если я реализую IEqualityComparer на этом типе, он дает мне единственные критерии получения отдельных объектов в наборе. Как я добираюсь, чтобы смочь назвать Отличным на нескольких критериях этого набора?

Например,

  class Product {
    string name ;
    string code ;
    string supplier ;
//etc 
}

Вообразите список таких объектов продукта. Иногда, я хочу получить список отличных имен в списке, и в некоторое другое время, список отличного поставщика. и т.д., Если я назову Отличными в списке этих продуктов, на основе способа, которым реализован IEqualityComparer, то он будет всегда использовать те же критерии, который не собирается служить моей цели.

5
задан Bhaskar 28 April 2010 в 15:05
поделиться

3 ответа

Вы можете использовать перегрузку Distinct () , которая принимает IEqualityComparer аргумент.

6
ответ дан 18 December 2019 в 06:49
поделиться

Вы также можете создать компаратор, который принимает аргументы функции для методов Equals и GetHashCode. Что-то вроде

class Foo
{
    public string Name { get; set; }
    public int Id { get; set; }
}    

class FooComparer : IEqualityComparer<Foo>
{
    public FooComparer(Func<Foo, Foo, bool> equalityComparer, Func<Foo, int> getHashCode)
    {
        EqualityComparer = equalityComparer;
        HashCodeGenerator = getHashCode;
    }

    Func<Foo, Foo, bool> EqualityComparer;
    Func<Foo, int> HashCodeGenerator;

    public bool Equals(Foo x, Foo y)
    {
        return EqualityComparer(x, y);
    }

    public int GetHashCode(Foo obj)
    {
        return HashCodeGenerator(obj);
    }
}

...

List<Foo> foos = new List<Foo>() { new Foo() { Name = "A", Id = 4 }, new Foo() { Name = "B", Id = 4 } };
var list1 = foos.Distinct(new FooComparer((x, y) => x.Id == y.Id, f => f.Id.GetHashCode()));
3
ответ дан 18 December 2019 в 06:49
поделиться

Просто предоставьте разные реализации IEqualityComparer для разных вызовов Distinct . Обратите внимание на разницу между IEquatable и IEqualityComparer - обычно тип не должен реализовывать IEqualityComparer сам по себе (поэтому Product не будет реализовывать IEqualityComparer <Продукт> ). У вас будут разные реализации, такие как ProductNameComparer, ProductCodeComparer и т. Д.

Однако другой альтернативой является использование DistinctBy в MoreLINQ

var distinctProducts = products.DistinctBy(p => p.name);
14
ответ дан 18 December 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: