Решение, которое я в итоге использовал, не может быть описано как быстрое, но это не мое дело, и оно делает то, что я хочу, потому что оно может быть использовано повторно и не ограничено каким-либо конкретным классом.
Он использует библиотеку Newtonsoft.Json для сериализации объекта в строку, а затем сравнивает результат. Это также имеет преимущество работы с анонимными классами и вложенными классами.
Я предполагаю, что способ сравнения заключается в том, что он сначала вызывает GetHashCode для обоих объектов, а если они совпадают, то вызывает Equals, что в этой подпрограмме будет означать, что соответствующие объекты будут сериализованы дважды.
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>());
}
}
Чтобы использовать его, вы меняете Except на ExceptUsingJSonCompare, например:
var differences = list2.ExceptUsingJSonCompare(list1);