Skip to content

Instantly share code, notes, and snippets.

@tomfanning
Created June 20, 2017 08:53
Show Gist options
  • Save tomfanning/3999647649786a2a66964f5142709250 to your computer and use it in GitHub Desktop.
Save tomfanning/3999647649786a2a66964f5142709250 to your computer and use it in GitHub Desktop.
C# reflection-based object diff
public class Compared
{
public object Left { get; set; }
public object Right { get; set; }
}
public static System.Collections.Generic.Dictionary<string, Compared> Diff(object o1, object o2)
{
var result = new System.Collections.Generic.Dictionary<string, Compared>(StringComparer.Ordinal);
if (o1.GetType() != o2.GetType())
{
throw new ArgumentException("Objects are not of the same type");
}
var oType = o1.GetType();
foreach (System.Reflection.PropertyInfo prop in oType.GetProperties())
{
object o1Value = prop.GetValue(o1);
object o2Value = prop.GetValue(o2);
#warning This only supports collections of primitives, not collections of collections. Fine for our purposes but not general purpose without further work.
if (prop.PropertyType != typeof(string) && typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.PropertyType))
{
var seq1 = (System.Collections.IEnumerable)o1Value;
var seq2 = (System.Collections.IEnumerable)o2Value;
int cnt1 = seq1.Cast<object>().Count();
int cnt2 = seq2.Cast<object>().Count();
if (cnt1 != cnt2)
{
result.Add(prop.Name, new Compared { Left = $"{cnt1} items", Right = $"{cnt2} items" });
}
var enumerator1 = seq1.GetEnumerator();
var enumerator2 = seq2.GetEnumerator();
for (int i = 0; i < cnt1; i++)
{
enumerator1.MoveNext();
enumerator2.MoveNext();
var o1eValue = enumerator1.Current;
var o2eValue = enumerator2.Current;
if (!object.Equals(o1eValue, o2eValue))
{
result.Add(prop.Name, new Compared { Left = $"item {i}={o1eValue}", Right = $"item {i}={o2eValue}" });
}
}
}
else
{
if (!object.Equals(o1Value, o2Value))
{
result.Add(prop.Name, new Compared { Left = o1Value, Right = o2Value });
}
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment