Comparing Two Complex Objects in C#

Introduction

Often, developers encounter a common problem of comparing two complex objects or classes created in code. Most of the time, developers prefer to use the IEquatable approach to actually create an IComparer so that he can define what determines that two of your objects are equal.

But, it’s difficult to compare objects that contain nested elements. An objects comparer NuGet package will solve such kinds of complex object comparison problems.

By using the NuGet framework, a developer can perform an object-to-object comparer that allows us to compare objects recursively, member by member. An objects comparer can be considered a ready-to-use framework or as a starting point for similar solutions.

.NET Object Compare

In .NET, objects can be compared with the == operator, with the Equals(Object) member, with the Object.Equal (Object, Object) method, or by using custom comparators that implement one of or more of the IEquatable<T>, IComparable, IStructuralEquatable, or IStructuralComparable interfaces.

  • Object.Equal: A developer can override the Object.Equal() method in the class, and then determine what makes the objects equal there. By default, Object.Equal() will compare your objects’ references.
  • Implement IComparable: IComparable is a neat interface that gives an object the Compare capability. As the comments mention, this will let you define how to compare the objects based on whatever criteria you want.
  • Implement CompareBy() Methods: A developer can implement methods for each possible type—CompareByInt() or CompareByString()—but this method depends on you knowing what you’re going to have when you do it.

Examples of Comparing Two Complex Objects

To demonstrate complex object comparison, I have created a .NET console application from Visual Studio and added ObjectCompare by using the NuGet package manager.

Object compare console project created
Figure 1: Object compare console project created

Next, create two classes, named MyClassCompare1 and MyClassCompare2. Also, write code in the Main () function as shown in the following code snippet to use objects comparer.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ObjectsComparer.Utils;
using ObjectsComparer.Exceptions;
using ObjectsComparer;
using System.Diagnostics;

namespace ObjectCompareExample
{
   class ObjectCompare
   {

      static void Main(string[] args)
      {
         // Initialize objects and comparer
         var object1 = new MyClassCompare1 { StringProperty =
            "String", IntProperty = 1, IntProperty2 = 2 };
         var object2 = new MyClassCompare1 { StringProperty =
            "String", IntProperty = 1 };
         var comparer = new ObjectsComparer.Comparer
            <MyClassCompare1>();
         // Compare objects
         IEnumerable<Difference> differences;
         var isEqual = comparer.Compare(object1, object2,
            out differences);
         // Print results
         Console.WriteLine(isEqual ? "Objects are equal" :
            "Objects are not equal");
         Console.Read();
      }
   }

   public class MyClassCompare1
   {
      public string StringProperty { get; set; }
      public int IntProperty { get; set; }
      public int IntProperty2 { get; set; }
      public MyClassCompare2 SubClass { get; set; }
   }
   public class MyClassCompare2
   {
      public bool BoolProperty { get; set; }
   }

}

The output of the preceding code would be ‘Objects are equal’.

For enumerables, such as arrays, collections, lists, dictionaries, and so forth, we can have a different number of elements or some elements can have different values. The following EnumerablesCompre() function demonstrates how to compare a single dimensional array.

static void EnumerablesCompre()
{
   var myarray = new[] { "Value1", "Value1", "Value1" };
   var myarray1 = new[] { "Value2", "Value2", "Value2" };
   var comparer = new ObjectsComparer.Comparer<string[]>();
   IEnumerable<Difference> differences;
   var isEqual = comparer.Compare(myarray, myarray1,
      out differences);
   // Print results
   Console.WriteLine(isEqual ? "Objects are equal" : "Objects are
      not equal");
   Console.Read();
}

If you have a requirement of building an object to work during runtime, use ExpandoObject to create an object to add properties, methods, and events during execution.

For comparing two ExpandoObjects, you can refer the following example.

static void ExpandoObjectObjectCompare()
{

   dynamic mydynamicobject = new ExpandoObject();
   mydynamicobject.Field1 = "Value1";
   mydynamicobject.Field2 = 10;
   mydynamicobject.Field4 = 20;
   dynamic mydynamicobject1 = new ExpandoObject();
   mydynamicobject1.Field1 = "Value2";
   mydynamicobject1.Field3 = false;
   mydynamicobject1.Field4 = "Value3";
   var comparer = new ObjectsComparer.Comparer();
   IEnumerable<Difference> differences;
   var isEqual = comparer.Compare(mydynamicobject,
      mydynamicobject1, out differences);
   // Print results
   Console.WriteLine(isEqual ? "Objects are equal" : "Objects are
      not equal");
   Console.Read();
}

Now, for DynamicObject compare, you can refer to the following example.

static void DynamicObjectCompare()
{

   dynamic mydynamicobject = new DynamicDictionary();
   mydynamicobject.Field1 = "Value1";
   mydynamicobject.Field3 = true;
   dynamic mydynamicobject1 = new DynamicDictionary();
   mydynamicobject1.Field1 = "Value2";
   mydynamicobject1.Field2 = 8;
   mydynamicobject1.Field3 = 1;
   var comparer = new ObjectsComparer.Comparer();
   IEnumerable<Difference> differences;
   var isEqual = comparer.Compare(mydynamicobject,
      mydynamicobject1, out differences);
   // Print results
   Console.WriteLine(isEqual ? "Objects are equal" : "Objects are
      not equal");
   Console.Read();
}

Conclusion

That’s it for today. Enjoy!

The Source Code of Objects Comparer can be found in this link.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read