2010-04-28 80 views
5

我有一個對象的集合,每個對象都有幾個屬性。我經常需要爲此集合中的許多屬性獲取不同值的列表。如果我在這種類型上實現了IEqualityComparer,它給了我一個獲得集合中不同對象的標準。如何能夠針對此集合的多個條件調用Distinct?列表<T> .Distinct()在C#中 - EqualityComparer的多個條件?

例如,

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

想象這樣的產品的對象的列表。 有時,我想獲得列表中不同名稱的列表,並且在某些時候,列出不同的供應商。 如果我根據IEqualityComparer的實施方式對這些產品的列表調用Distinct,它將始終使用相同的標準,這不符合我的目的。

回答

13

只需爲Distinct的不同調用提供不同的IEqualityComparer實現。請注意0​​和IEqualityComparer之間的區別 - 通常,一個類型本身不應該執行IEqualityComparer(因此Product不會執行IEqualityComparer<Product>)。你有不同的實現,如ProductNameComparer,ProductCodeComparer等

然而,另一種選擇是使用DistinctByMoreLINQ

var distinctProducts = products.DistinctBy(p => p.name); 
+0

將選擇作爲答案,但是從漢斯2分鐘早日答覆。 – Bhaskar 2010-04-28 15:24:38

3

你也可以創建一個接受函數參數的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()));