只需在c#中比较两个对象的属性

max*_*axp 5 c# asp.net serialization c#-4.0

我有一个有很多属性的课程.浅拷贝足以完全复制对象.

我需要比较一个对象,以检查它是否包含与另一个完全相同的值.

我的想法:

第一个也是最明显的解决方案就是创建一个巨大的方法块,一个接一个地比较每个属性.

第二种方法是序列化每个对象并散列文件或对其执行某种md5校验和.(这实际上是否有效).

第三种是对对象进行某种反思,这会自动化第一个选项,但会增加复杂程度.

速度真的不是问题.

有兴趣听到思想,或者我缺少的任何其他方法来做这样的事情.

编辑:谢谢大家.我的解决方案:(现在修改为通用项目的递归).

  public static bool IsSame<T>(T objA, T objB)
        {
            var type = typeof(T);
            var properties = type.GetProperties();
            foreach (var pi in properties.Where(a => a.CanRead))
            {
                if (pi.Name == "Item")
                {
                    var piCount = properties.FirstOrDefault(a => a.Name == "Count");
                    int count = -1;
                    if (piCount != null && piCount.PropertyType == typeof(System.Int32))
                        count = (int)piCount.GetValue(objA, null);
                    if (count > 0)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            dynamic child1 = pi.GetValue(objA, new object[] { i });
                            dynamic child2 = pi.GetValue(objB, new object[] { i });
                            return IsSame(child1, child2);
                        }
                    }
                }
                else
                {
                    var val1 = type.GetProperty(pi.Name).GetValue(objA, null);
                    var val2 = type.GetProperty(pi.Name).GetValue(objB, null);
                    if (val1 != val2 && (val1 == null || !val1.Equals(val2)))
                        return false;
                }
            }
            return true;
        }
Run Code Online (Sandbox Code Playgroud)

Ric*_*lly 6

大多数序列化程序旨在确保数据在序列化和反序列化期间保持其完整性,而不是生成一致的序列化格式.我会避免为此目的使用序列化.

您可以考虑实现IEquatable,让每个实例都能够将自己与同一类型的实例进行比较.或者一个类为您实现IEqualityComparer的比较.他们如何做这种比较可能是一个接一个地比较属性或使用反射的"大方法".

反射可以是实现目标的一种相当快速和简单的方法,但可能会导致问题(例如,如果有人为您的类型添加了一个不应包含在内的属性用于比较相等性),但显然反过来也是如此(某人)添加应检查相等性的属性,但不更新相等性比较).您使用哪种方法通常应取决于团队对每种方法的适应程度,以及使用该类的上下文.

在您的情况下,我可能建议使用基于反射的方法,因为您希望检查浅克隆操作的结果,因此所有属性应该相等.

顺便说一句,我建议使用MemberwiseClone方法创建克隆,这将减少对这种严格测试的需要.

  • 我想你想要IEquatable而不是IComparable.IComparable用于排序,而不是等价. (3认同)

joe*_*ish 6

第三个选项(反射)将是最慢的,但它也将是最强大/可测试的.

哈希代码与第一个选项非常相似,因为您必须调用所有成员变量,因此每次修改成员变量列表时,1和2都需要您更新.Equals(obj).GenerateHash()方法.

这里有一些代码可以帮助您入门:

        foreach (FieldInfo field in this.GetType().GetFields())
        {
            if (o[field.Name] == null)
            {
                if (!field.GetValue(this).Equals(o[field.Name]))
                    return false;
            }
            else
            {
                return false;
            }
        }

        return true;
Run Code Online (Sandbox Code Playgroud)