Compare 2 object of the same class

Recently, I ran into a problem of comparing 2 objects of the same class in C#. I need to know which fields/properties are changed.

Here is the example:

SampleClass 
{
  string sampleField1;
  int sampleField2;
  CustomClass sampleField3; 
}

And I have 2 SampleClass object, object1 and object2, for example. These 2 objects have some different field value.

Upvotes: 4

Views: 2723

Answers (3)

DavidG
DavidG

Reputation: 119186

A slight modification of another answer posted here, but this one works with properties that are not string types, doesn't use an internal list and does automatic some preliminary type checking as it's generic:

public IEnumerable<string> ChangedFields<T>(T first, T second)
{
    if (first.GetType() != second.GetType())
        throw new ArgumentOutOfRangeException("Objects should be of the same type");

    var properties = first
        .GetType()
        .GetProperties();
        
    foreach (var property in properties)
    {
        if(!object.Equals(property.GetValue(first), property.GetValue(second)))
        {
            yield return property.Name;
        }
    }
}

Upvotes: 3

Bakri Bitar
Bakri Bitar

Reputation: 1697

If you want Generic way to get all changed properties

you can use this method (and it is using reflection ^_^ )

    public List<string> GetChangedProperties(object obj1, object obj2)
    {
        List<string> result = new List<string>();

        if(obj1 == null || obj2 == null )
            // just return empty result
            return result;

        if (obj1.GetType() != obj2.GetType())
            throw new InvalidOperationException("Two objects should be from the same type");

        Type objectType = obj1.GetType();
          // check if the objects are primitive types
        if (objectType.IsPrimitive || objectType == typeof(Decimal) || objectType == typeof(String) )
            {
                // here we shouldn't get properties because its just   primitive :)
                if (!object.Equals(obj1, obj2))
                    result.Add("Value");
                return result;
            }

        var properties = objectType.GetProperties();

        foreach (var property in properties)
        {
            if (!object.Equals(property.GetValue(obj1), property.GetValue(obj2)))
            {
                result.Add(property.Name);
            }
        }

        return result;

    }

Please note that this method only gets Primitive type properties that have changed and reference type properties that refer to the same instance

EDIT: Added validation in case if obj1 or obj2 is primitive type (int,string ... ) because I tried to pass string object and it will give an error also fixed bug of checking whether the two values are equal

Upvotes: 5

Stas Sh
Stas Sh

Reputation: 676

If you need to compare two objects as part of your business logic reflection is the way to go, unless of course you can write comparator classes for each type.

If you want to compare two objects at run time during debugging, there is a neat plugin called Oz Code that can do that for you, something like this:

enter image description here

Upvotes: 2

Related Questions