比较两个对象并找出它们之间的不同之处。

110

什么是比较两个对象并找出它们之间的差异的最佳方法?

Customer a = new Customer();
Customer b = new Customer();
2个回答

249

一种灵活的解决方案:您可以使用反射枚举所有属性并确定哪些属性相等,哪些不相等,然后返回某些属性和两个不同的值的列表。

这是一个很好的开始,适用于您所要求的代码示例。它目前只查看Field值,但您可以添加任意数量的其他组件以通过反射进行检查。它使用扩展方法实现,因此您的所有对象都可以使用它。

使用方法:

    SomeCustomClass a = new SomeCustomClass();
    SomeCustomClass b = new SomeCustomClass();
    a.x = 100;
    List<Variance> rt = a.DetailedCompare(b);

我用于比较的示例类

    class SomeCustomClass
    {
        public int x = 12;
        public int y = 13;
    }

重点内容

using System.Collections.Generic;
using System.Reflection;

static class extentions
{
    public static List<Variance> DetailedCompare<T>(this T val1, T val2)
    {
        List<Variance> variances = new List<Variance>();
        FieldInfo[] fi = val1.GetType().GetFields();
        foreach (FieldInfo f in fi)
        {
            Variance v = new Variance();
            v.Prop = f.Name;
            v.valA = f.GetValue(val1);
            v.valB = f.GetValue(val2);
            if (!Equals(v.valA, v.valB))
                variances.Add(v);

        }
        return variances;
    }


}
class Variance
{
    public string Prop { get; set; }
    public object valA { get; set; }
    public object valB { get; set; }
}

36
使用 if (!Equals(v.valA, v.valB)) 替代 if (!v.valA.Equals(v.valB)) 可以防止出现空引用异常。 - Jerome2606
为什么不使用自动属性? - Thomas Ayoub
7
如果 .GetFields() 方法未返回你所需的所有内容(例如私有字段),请参阅此帖子:https://dev59.com/qHNA5IYBdhLWcg3wPLP- - Kjensen
8
5年后,这完全是我一直在寻找的。我只需要切换到GetProperties就可以了,它完美地解决了我的问题(满足了我的需求)。 - Francisc0
10
我喜欢这个想法,但是这里的代码不能运行。这里有一个示例,展示了一些修复措施:https://dotnetfiddle.net/FhzcrS - Don Rolling
显示剩余4条评论

14

Equals方法和IEquatable<T>接口可用于判断两个对象是否相等,但它们无法让你知道对象之间的差异。您可以通过比较每个属性值使用反射。

另一种方法是将这些实例序列化为某些文本格式,并在结果字符串(XML、JSON等)中比较差异。


3
我认为他不是在寻找相等测试,而是在收集两个对象不匹配的原因。 - deepee1
当然可以,但是考虑到我们不知道Customer类中包含什么内容,这并没有太多意义。 - Rob
1
@deepee1,@Rob,我同意EqualsIEquatable<T>不能用于查找差异。在这种情况下可以使用反射。 - Darin Dimitrov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接