比较两个对象数组而不知道它们的类型

时间:2016-11-03 07:41:22

标签: c# .net

我需要你的帮助!我想比较两个对象数组。这些数组应该相同但不一样。

背景:

我正在编写一个函数来与同类型的对象树进行比较。通过反射,我在第二个对象中检查第一个对象的每个属性:

  • 我找到一个原始类型我比较它,如果找到差异我 将其保存在列表中

  • 我找到一个对象,我在两个对象上调用方法(递归)

  • 我找到一个数组,如果它们是相同的,我检查长度,我解析 数组并将每个值与方法进行比较(递归)。 在这种情况下,我需要对数组进行排序,以确保对象的顺序相同

我想到的方式,但无法实现:

  • 我无法覆盖类的equals方法,有很多 类和它们由基于XSD文件的工具自动生成。

  • 我试图在IComparer接口中使用GetHashCode,但是 GetHashCode使用引用,然后排序没有任何意义。

您是否知道如何继续进行?我正在考虑根据内容生成一个HashCode,但我怎么能一般地做呢?

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

我找到了这个解决方案......

我实现了一个IComparer,并将我的对象与Strings中转换的流进行比较(不太优雅,但效果很好):

    private class ObjectStreamComp : IComparer
    {
        public int Compare(Object x, Object y )  
        {

            BinaryFormatter binaryFormatter = new BinaryFormatter();

            using (MemoryStream mx = new MemoryStream())
            using (MemoryStream my = new MemoryStream())
            {
                binaryFormatter.Serialize(mx, x);
                binaryFormatter.Serialize(my, y);

                mx.Position = 0;
                my.Position = 0;

                return (new StreamReader(mx)).ReadToEnd().CompareTo((new StreamReader(my)).ReadToEnd());
            }   
        }
    }

我可以使用序列化,因为我的对象树标记为Serialized(用于XML序列化)。

我这样使用它:

Array.Sort(valueReferenceArray, ((IComparer)new ObjectStreamComp()));
Array.Sort(valueCreatedArray, ((IComparer)new ObjectStreamComp()));

答案 1 :(得分:0)

你知道只使用反射来比较两个对象树会让你遇到麻烦,如果性能有问题吗?您应该尽可能避免反射,特别是在处理大型对象树时。对概念验证的反思是可以的,但实际上并不是更多。

但重写Equals-Method有什么问题? XSD通常不会生成Equals-methods,因此您可以使用部分类自由扩展这些生成的类。这正是为mic静态和生成代码创建的部分类的原因。

编辑:请注意,如果您重写等于,则还必须适当地覆盖GetHashCode。但是,这意味着默认情况下,使用类的所有对象都将使用值相等。如果这不是您想要的,那么Alex Pashkin建议的自定义IEqualityComparer是更好的选择。

答案 2 :(得分:0)

在这种情况下,您可以实现自己的IEqualityComparer

public class MyComparer<T> : IEqualityComparer<T> where T : class
{        
    public bool Equals(T x, T y)
    {
        //your code here
    }
    public int GetHashCode(T obj)
    {
        return obj.GetHashCode();
    }
}

例如,如果您想在exept中使用它,您只需执行此操作

var list1 = new List<object>();
var list2 = new List<object>();
var rest = list1.Except(list2, new MyComparer<object>());