2009-07-01 22 views
29

Tôi có điều nàyIEqualityComparer cho vô danh loại

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();); 

Tôi muốn làm điều này nếu nó ở đâu cho phép

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

tôi đã cố gắng sử dụng generic LambdaComparer nhưng vì im sử dụng các loại vô danh không có loại kết hợp nó với.

"Giúp tôi Obi-Wan Kenobi, bạn đang hy vọng duy nhất của tôi"

+3

Câu hỏi hay, tôi chỉ đang tìm kiếm một điều tương tự. Không thể tin được nó không có trong thư viện chuẩn. – orip

+0

Nó có thể giúp [Quấn một đại biểu trong IEqualityComparer] (http://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer) – marbel82

Trả lời

16

Bí quyết là để tạo ra một Comparer mà chỉ hoạt động trên các loại suy ra. Ví dụ:

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); 
    } 
} 

Bây giờ tôi có thể làm như sau ... giải pháp hacky:

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

Rất trơn. Im suy nghĩ mặc dù rằng trong lợi ích của việc viết mã sạch tôi nên tạo một giao diện để sử dụng như là T trong một IEqualityComparer . – kjgilla

+0

Tôi không thể giải quyết vấn đề. Xem bên dưới. – Tormod

3

Phần lớn thời gian khi bạn so sánh (đối với bình đẳng hoặc sắp xếp) bạn quan tâm trong việc lựa chọn các phím để so sánh, không phải là phương trình bình đẳng hay so sánh (đây là ý tưởng đằng sau API sắp xếp danh sách của Python).

Có một ví dụ so sánh bình đẳng khóa ví dụ here.

0

Tôi lưu ý rằng câu trả lời của JaredPar không hoàn toàn trả lời câu hỏi vì các phương pháp đã đặt như Phân biệt và Ngoại lệ yêu cầu IEqualityComparer<T> không phải là IComparer<T>. Sau đây giả định rằng một IEquatable sẽ có một GetHashCode phù hợp, và nó chắc chắn có một phương thức Equals phù hợp.

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); 
    } 
} 

Trường hợp suy luận tương tự từ thủ thuật lớp tĩnh được sử dụng như trong câu trả lời của JaredPar.

Nói chung, bạn có thể cung cấp hai số Func s: a Func<T, T, bool> để kiểm tra tính bình đẳng và Func<T, T, int> để chọn mã băm.

+0

Mặc dù câu trả lời của JaredPar là về so sánh, nó cho ý tưởng làm thế nào để đi abt nó. – nawfal

Các vấn đề liên quan