0

I have 2 List<Animal> which I would like to compare and find the difference between the 2 List<Animal> objects.

Animal object contains the following properties.

Id

Name

Age

List list1 has a count of 10 Animal objects in it, where as list2 has another 10 Animal objects in it. In these 2 Lists there are 2 items (Animal objects that the same)

When I use the Except function, I was hoping that remainingList will contain Only the objects that aren't common between the 2 list. However, remainingList contains a copy of list1 instead.

How can I solve this ?

 List<Animal> remainingList = list1.Except(list2).toListAsync();
Community
  • 1
  • 1
Illep
  • 16,375
  • 46
  • 171
  • 302
  • 4
    I strongly suspect the problem is that `Animal` doesn't override `Equals`/`GetHashCode` or implement `IEquatable`... so `Except` will only compare `Animal` *references* rather than the values of properties. – Jon Skeet Oct 10 '18 at 11:03
  • Is there a workaround for this. Rather than using `Except` can I use any other solution ? – Illep Oct 10 '18 at 11:08
  • @Illep - See first duplicated question - there is some explanation about passing an `IEqualityComparer` instead of overriding the methods – Gilad Green Oct 10 '18 at 11:16

1 Answers1

5

You need to Override Equal and GetHashCode in your class. Something like this:

public class Animal
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public override bool Equals(object obj)
    {
        if (!(obj is Animal))
            return false;
        var p = (Animal)obj;
        return p.Id == Id && p.Name == Name && p.Age == Age;
    }

    public override int GetHashCode()
    {
        return String.Format("{0}|{1}|{2}", Id, Name, Age).GetHashCode();
    }
}

Or with newer versions of C# you can:

public override int GetHashCode() => $"{Id}|{Name}|{Age}".GetHashCode();
Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
  • I think it is strongly adviced that Immutable properties are used to calculate `GetHashCode` and `Equals`. Morever, may I suggest `Property.GetHashcode()^Property.GetHashcode()....` for hashcode? – Hasan Emrah Süngü Oct 10 '18 at 11:07
  • I would also add a check for `if (obj == null) return false`. In any case where the right hand side is null, the instances are not equal. – Mike Hofer Oct 10 '18 at 11:08