简体   繁体   中英

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.

  • Can anyone know the best approach to get which fields are different?

  • And how to get the (string) names of that different fields/properties?

  • I heard of Reflection in .Net. Is that the best approach in this situation?
  • And if we didn't have the CustomClass field? (I just make this field for a more general approach, that field does not exist in my case)

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

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 (obj1.GetType() != obj2.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;
        }
    }
}

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:

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM