2015-06-30 1 views
0

У меня есть следующий простой объект:IEqualityComparer <T> не работает со списком <T> .distinct() метод

public class Net : IEqualityComparer<Net> 
{ 
    public string Name { get; private set; } 
    public int Id { get; set; } 

    private Gate _inGate; 
    private Gate _outGate; 
    private NetValue _value = NetValue.NotSet; 
    private bool _isMiddleNet; 

    //constructor and stuff!!!..... 

    //Equality comparer 
    public bool Equals(Net x, Net y) 
    { 
     return (x.Id == y.Id && x.Name == y.Name); 
    } 

    public int GetHashCode(Net obj) 
    { 
     return obj.Id.GetHashCode()^obj.Name.GetHashCode(); 
    } 

    public override int GetHashCode() 
    { 
     return 13 * Id.GetHashCode() + 7 * Name.GetHashCode(); 
    } 

Поэтому в основном я заинтересован, чтобы сказать 2 экземпляра этого объекта равны тогда и только тогда, когда их Id и Name члены равны ...

Но где-то в другом классе я должен List<Net>, и я хочу, чтобы выполнить различие в этих списках:

inputNetsA = inputNetsA.Distinct().ToList(); 
    inputNetsB = inputNetsB.Distinct().ToList(); 

Но это не работает так, как никогда! Что я делаю не так?

+1

Сторона q: почему 2 реализации GetHashCode настолько различны в вашем образце? А где реализация 'object.Equals'? См. Http://stackoverflow.com/questions/4095395/whats-the-role-of-gethashcode-in-the-iequalitycomparert-in-net и связанные вопросы для информации ... –

ответ

2

Вам необходимо сделать объекты IEquatable<T>. IEqualityComparer<T> - это интерфейс для объектов, который сравнивает два объекта с eachother. IEquatable<T> используется для сравнения объекта с другим объектом того же типа.

В противном случае, если вы хотите использовать IEqualityComparer<T>, он должен быть передан методу Distinct().

// better to extend off of EqualityComparer<T> instead of 
//  implementing IEqualityComparer<T> directly 
public class NetComparer : EqualityComparer<Net> 
{ 
    public override bool Equals(Net x, Net y) 
    { 
     return (x.Id == y.Id && x.Name == y.Name); 
    } 

    public override int GetHashCode(Net obj) 
    { 
     return obj.Id.GetHashCode()^obj.Name.GetHashCode(); 
    } 
} 

inputNetsA = inputNetsA.Distinct(new NetComparer()).ToList(); 
+0

Большое спасибо. Я получаю NullReference в этой строке 'return obj.Id.GetHashCode()^obj.Name.GetHashCode();' –

+0

Это нормально, если я просто возвращаю null в GetHashCode? –

+0

Возвращаемый тип 'GetHashCode()' is 'int', вы не можете вернуть' null'. Все, что я могу сказать об этом, вернет все, что подходит для этого типа. Если один из членов объекта, который используется для генерации хэш-кода, может быть «null», может быть, это не подходящий ключ? В противном случае вам нужно решить, как справиться с ними. например, рассматривать их как «0» –

Смежные вопросы