C#中两个对象之间的差异

use*_*481 7 c# reflection comparison

我想知道如何找到同一类的两个对象之间的区别.因此,如果我有一个Person类,唯一的区别是Age,它将返回不同的字段/字段.

谢谢

LBu*_*kin 9

这不是C#(或.NET真正)直接支持的东西,但是您可以手动为特定类型实现某些东西,或编写使用反射来区分任意对象的代码.

如果选择后者,则必须确定要进入对象图的深度,以确定两个实例是否相同,以及如何比较某些基本类型的相等性(例如,双精度).

编写基于反射的差分算法比起初看起来更困难 - 个人而言,我会直接为您需要的类型(或帮助类)实现此功能.


Mic*_*ann 8

这是我在调试时使用的一些简单代码:

    //This structure represents the comparison of one member of an object to the corresponding member of another object.
    public struct MemberComparison
    {
        public readonly MemberInfo Member; //Which member this Comparison compares
        public readonly object Value1, Value2;//The values of each object's respective member
        public MemberComparison(MemberInfo member, object value1, object value2)
        {
            Member = member;
            Value1 = value1;
            Value2 = value2;
        }

        public override string ToString()
        {
            return Member.Name + ": " + Value1.ToString() + (Value1.Equals(Value2) ? " == " : " != ") + Value2.ToString();
        }
    }

    //This method can be used to get a list of MemberComparison values that represent the fields and/or properties that differ between the two objects.
    public List<MemberComparison> ReflectiveCompare<T>(T x, T y)
    {
        List<MemberComparison> list = new List<MemberComparison>();//The list to be returned

        foreach (MemberInfo m in typeof(T).GetMembers(BindingFlags.NonPublic | BindingFlags.Instance))
            //Only look at fields and properties.
            //This could be changed to include methods, but you'd have to get values to pass to the methods you want to compare
            if (m.MemberType == MemberTypes.Field)
            {
                FieldInfo field = (FieldInfo)m;
                var xValue = field.GetValue(x);
                var yValue = field.GetValue(y);
                if (!object.Equals(xValue, yValue))//Add a new comparison to the list if the value of the member defined on 'x' isn't equal to the value of the member defined on 'y'.
                    list.Add(new MemberComparison(field, yValue, xValue));
            }
            else if (m.MemberType == MemberTypes.Property)
            {
                var prop = (PropertyInfo)m;
                if (prop.CanRead && prop.GetGetMethod().GetParameters().Length == 0)
                {
                    var xValue = prop.GetValue(x, null);
                    var yValue = prop.GetValue(y, null);
                    if (!object.Equals(xValue, yValue))
                        list.Add(new MemberComparison(prop, xValue, yValue));
                }
                else//Ignore properties that aren't readable or are indexers
                    continue;
            }
        return list;
    }
Run Code Online (Sandbox Code Playgroud)

要使用它,您的代码可能如下所示:

public static void Main()
{
    MyObject object1 = new MyObject();
    MyObject object2 = new MyObject();
    // ...Code that changes object1 and/or object2...

    //Here's your answer: a list of what's different between the 2 objects, and each of their different values.
    //No type parameters are needed here- typeof(MyObject) is implied by the coincident types of both parameters.
    List<MemberComparison> changes = ReflectiveCompare(object1, object2);
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案,但比较应该是:!object.Equals(xValue,yValue)来处理当yValue为null时. (2认同)