Compare Objects Based On Their Properties

When we do testing, we often need to compare 2 objects. The problems are:

  • It is often that we don’t bother to override GetHashCode and Equals method. Laziness plays part here :) .
  • We often need to ignore some properties.

There are properties that need special comparison method.
They are different types, but have a similar set of properties. The worst case is you are comparing against anonymous / upcasted objects. Once again, reflection solves the problem easily for us.

bool AreEqual(object obj1, object obj2, ICollection<string> lstException, 
IDictionary<string, Func<object, object, bool>> methodDictionary)
{
    var type1 = obj1.GetType();
    var arrProperty = type1.GetProperties();
    foreach (var property in arrProperty)
    {
        if (lstException != null && lstException.Contains(property.Name))
            continue;
        var value1 = property.GetValue(obj1, null);
        var value2 = property.GetValue(obj2, null);
        if ((value1 == null && value2 != null) || (value1 != null && value2 == null))
            return false;
        if (value1 == null) continue;
        if (methodDictionary == null || !methodDictionary.ContainsKey(property.Name))
        {
            if (!value1.Equals(value2))
                return false;       
        }
        else
        {
            var method = methodDictionary[property.Name];
            if (method != null)
                return method(value1, value2);
            return false;
        }
    }
    return true;
}

Example of usage:

void TestCompare()
{
    var object1 = new {Isbn = 10203299399, Name = "Book One", Price = 300, Author = new {ID = 123, Name = "Gray"}};
    var object2 = new {Isbn = 10203299399, Name = "Book One", Price = 230, Author = new {ID = 123, Name = "Gray"}};
    var result=AreEqual(object1, object2, new List<string> {"Price"}, new Dictionary<string, Func<object, object, bool>>
       {
            {"Author",(obj1,obj2)=>object1.Author.ID==object2.Author.ID}
       });
    Console.WriteLine(result.ToString());
}

In the above method, we compare 2 anonymous objects, ignore Price property, and compare Author property based on their ID.

I often call this method inside nUnit’s Assert.IsTrue .