Search code examples
c#.netlinqiequalitycomparer

IEqualityComparer<T> does not work with List<T>.Distinct() method


I have the following simple object:

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

So basically I am interested to say 2 instance of this object are equal if and only if their Id and Name members are equal...

But somewhere else in another class I have to List<Net> and I want to perform distinction on these lists:

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

But this does not work what so ever! What am I doing wrong?


Solution

  • You need to make the objects IEquatable<T>. The IEqualityComparer<T> is an interface for objects that compares two objects with eachother. The IEquatable<T> is used for comparing an object with another object of the same type.

    Otherwise, if you wanted to use IEqualityComparer<T>, it's meant to be passed in to the Distinct() method.

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