2009-07-01 109 views
29

我有這個的IEqualityComparer匿名類型

var n = ItemList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList(); 
n.AddRange(OtherList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList();); 

我想,如果它這樣做在允許的情況

n = n.Distinct((x, y) => x.Vchr == y.Vchr)).ToList(); 

我使用通用LambdaComparer但因爲即時通訊使用匿名類型的嘗試沒有類型與之相關聯。

「幫我歐比旺·克諾比,你是我唯一的希望」

+3

偉大的問題,我只是在尋找同樣的事情。令人難以置信的是它不在標準庫中。 – orip 2009-08-06 14:57:21

+0

它可以幫助[包裹在IEqualityComparer中的委託](http://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer) – marbel82 2016-10-07 15:10:58

回答

16

關鍵是要建立一個比較器,僅適用於推斷類型。例如:

public class Comparer<T> : IComparer<T> { 
    private Func<T,T,int> _func; 
    public Comparer(Func<T,T,int> func) { 
    _func = func; 
    } 
    public int Compare(T x, T y) { 
    return _func(x,y); 
    } 
} 

public static class Comparer { 
    public static Comparer<T> Create<T>(Func<T,T,int> func){ 
    return new Comparer<T>(func); 
    } 
    public static Comparer<T> CreateComparerForElements<T>(this IEnumerable<T> enumerable, Func<T,T,int> func) { 
    return new Comparer<T>(func); 
    } 
} 

現在,我可以做以下...哈克解決方案:

var comp = n.CreateComparerForElements((x, y) => x.Vchr == y.Vchr); 
+0

非常漂亮。雖然我認爲,爲了編寫乾淨的代碼,我應該創建一個接口,以在IEqualityComparer中使用T作爲參數。 – kjgilla 2009-07-02 02:32:07

3

很多時候你比較(相等或排序)你有興趣選擇鍵時來比較,而不是相等或比較方法本身(這是Python列表排序API背後的想法)。

有一個示例關鍵字相等比較器here

0

我注意到JaredPar的回答並不完全回答這個問題,因爲像Distinct和Except這樣的設置方法不需要IEqualityComparer<T>而不是IComparer<T>。以下假設一個IEquatable將有一個合適的GetHashCode,它肯定有一個合適的Equals方法。

public class GeneralComparer<T, TEquatable> : IEqualityComparer<T> 
{ 
    private readonly Func<T, IEquatable<TEquatable>> equatableSelector; 

    public GeneralComparer(Func<T, IEquatable<TEquatable>> equatableSelector) 
    { 
     this.equatableSelector = equatableSelector; 
    } 

    public bool Equals(T x, T y) 
    { 
     return equatableSelector.Invoke(x).Equals(equatableSelector.Invoke(y)); 
    } 

    public int GetHashCode(T x) 
    { 
     return equatableSelector(x).GetHashCode(); 
    } 
} 

public static class GeneralComparer 
{ 
    public static GeneralComparer<T, TEquatable> Create<T, TEquatable>(Func<T, TEquatable> equatableSelector) 
    { 
     return new GeneralComparer<T, TEquatable>(equatableSelector); 
    } 
} 

在JaredPar的答案中使用了與靜態類別技巧相同的推理。

爲了更一般,您可以提供兩個Func s:一個Func<T, T, bool>來檢查相等性,並且Func<T, T, int>選擇一個哈希碼。