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
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.
public class JSonEqualityComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
return String.Equals
(
Newtonsoft.Json.JsonConvert.SerializeObject(x),
Newtonsoft.Json.JsonConvert.SerializeObject(y)
);
}
public int GetHashCode(T obj)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(obj).GetHashCode();
}
}
public static partial class LinqExtensions
{
public static IEnumerable<T> ExceptUsingJSonCompare<T>
(this IEnumerable<T> first, IEnumerable<T> second)
{
return first.Except(second, new JSonEqualityComparer<T>());
}
}
To use it you swap Except with ExceptUsingJSonCompare, for example :
var differences = list2.ExceptUsingJSonCompare(list1);
You could try something like:
var differences = list2.Where(l2 =>
!list1.Any(l1 => l1.Name == l2.Name && l1.Size == l2.Size));
Or if you prefer:
var differences = list2.Where(l2 =>
list1.All(l1 => l1.Name != l2.Name || l1.Size != l2.Size));
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.