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.

+5
source share
3 answers

You can use Distinct () overload , which takes an argument of IEqualityComparer.

+6
source

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);
+13
source

, 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

All Articles