I am trying to find the difference between two generic lists, as in the example below. Even though t1 and t2 contain the same properties, they are not the same object, so I have need to implement an IEqualityComparer.
This appears to be working with this example, but the real class has several other properties and I also need to do the same with a few other class.
So I was wondering if I am re-inventing the wheel?
Is there an easier method of comparing all the properties of two objects? At the moment, I really only need to cope with class containing simple types, but it would be nice I have a comparer that worked with classes that contains instances of other classes.
void Main()
{
var t1 = new Sizes { Name = "Test" , Size = 1} ;
var t2 = new Sizes { Name = "Test" , Size = 1} ;
var list1 = new List<Sizes>();
var list2 = new List<Sizes>();
list1.Add(t1);
list2.Add(t2);
var differences = list2.Except(list1 , new SizesComparer());
// differences should be empty.
}
public class Sizes
{
public string Name { get; set; }
public int Size { get; set; }
}
public class SizesComparer : IEqualityComparer<Sizes>
{
bool IEqualityComparer<Sizes>.Equals(Sizes x, Sizes y)
{
return (x.Name.Equals(y.Name) && x.Size.Equals(y.Size));
}
int IEqualityComparer<Sizes>.GetHashCode(Sizes obj)
{
if (Object.ReferenceEquals(obj, null))
return 0;
return obj.Name.GetHashCode() + obj.Size;
}
}
You could try something like:
Or if you prefer:
Best way I usually go for is try have unique/composite key in each objectand that way you only compare the key part and dont have to compare other bits.
You could use Reflection which will go through each public property of the class (which will be very generic) and compare them, but that will be slower.
The solution which I ended up using could not be described as fast, but that is not a concern of mine and it does what I want in that it can be re-used and is not restricted to any particular class.
It uses the Newtonsoft.Json library to serialize the object to a string and then compares the result. This also has the advantage of working with anonymous classes and nested classes.
I am assuming that the way the comparison works is that it first calls GetHashCode on both objects and if they match it then calls Equals, which in this routine will mean that matching objects will be serialized twice.
To use it you swap Except with ExceptUsingJSonCompare, for example :