简体   繁体   English

比较同一类的2个对象

[英]Compare 2 object of the same class

Recently, I ran into a problem of comparing 2 objects of the same class in C#. 最近,我遇到了在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. 我有2个SampleClass对象,例如object1object2 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. 我在.Net听说过反思。 Is that the best approach in this situation? 在这种情况下,这是最好的方法吗?
  • And if we didn't have the CustomClass field? 如果我们没有CustomClass字段? (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 请注意,此方法仅获取已更改的Primitive类型属性和引用同一实例的引用类型属性

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 编辑:如果obj1obj2是原始类型(int,string ...),添加验证,因为我试图传递字符串对象,它会给出一个错误,修复了检查这两个值是否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: 稍微修改了这里发布的另一个答案,但是这个可以使用不是string类型的属性,不使用内部列表并自动进行一些初步类型检查,因为它是通用的:

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: 如果你想在调试期间在运行时比较两个对象,有一个叫做Oz Code的简洁插件可以为你做到这一点,如下所示:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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