У меня есть набор объектов, которые имеют несколько свойств в каждом из них. Я часто должен получать список отличных значений для многих свойств в этом наборе. Если я реализую IEqualityComparer на этом типе, он дает мне единственные критерии получения отдельных объектов в наборе. Как я добираюсь, чтобы смочь назвать Отличным на нескольких критериях этого набора?
Например,
class Product {
string name ;
string code ;
string supplier ;
//etc
}
Вообразите список таких объектов продукта. Иногда, я хочу получить список отличных имен в списке, и в некоторое другое время, список отличного поставщика. и т.д., Если я назову Отличными в списке этих продуктов, на основе способа, которым реализован IEqualityComparer, то он будет всегда использовать те же критерии, который не собирается служить моей цели.
Вы можете использовать перегрузку Distinct () , которая принимает IEqualityComparer аргумент.
Вы также можете создать компаратор, который принимает аргументы функции для методов 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()));
Просто предоставьте разные реализации IEqualityComparer
для разных вызовов Distinct
. Обратите внимание на разницу между IEquatable
и IEqualityComparer
- обычно тип не должен реализовывать IEqualityComparer
сам по себе (поэтому Product
не будет реализовывать IEqualityComparer <Продукт>
). У вас будут разные реализации, такие как ProductNameComparer, ProductCodeComparer и т. Д.
Однако другой альтернативой является использование DistinctBy
в MoreLINQ
var distinctProducts = products.DistinctBy(p => p.name);