List of <T> .Distinct () in C # - some criteria for EqualityComparer?
I have a set of objects that have several properties in each of them. I often need to get a list of different values for many properties of this collection. If I implement IEqualityComparer for this type, it gives me one criterion for getting individual objects in a collection. How do I get the ability to call Distinct on several criteria for this collection?
For instance,
class Product {
string name ;
string code ;
string supplier ;
//etc
}
Provide a list of such product objects. Sometimes I want to get a list of individual names in a list, and at some time, a list of individual suppliers. etc. If I name Distinct in the list of these products, based on how IEqualityComparer is implemented, it will always use the same criteria that will not serve my purpose.
Just specify different implementations IEqualityComparerfor different calls Distinct. Pay attention to the difference between IEquatableand IEqualityComparer- usually the type should not implement IEqualityComparerfor itself (therefore Productit will not implement IEqualityComparer<Product>). You will have different implementations like ProductNameComparer, ProductCodeComparer, etc.
However, another alternative is to use DistinctByin MoreLINQ
var distinctProducts = products.DistinctBy(p => p.name);
, 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()));