Compare 2 object of the same class

房东的猫 提交于 2019-12-10 18:49:48

问题


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)

回答1:


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




回答2:


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;
        }
    }
}



回答3:


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:



来源:https://stackoverflow.com/questions/31858359/compare-2-object-of-the-same-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!