简体   繁体   English

比较两个列表中对象的值

[英]Compare values of objects in two lists

I have two ObservableCollection<Model> , each model has 10 properties and there are approximately 30 objects within both collections in the beggining. 我有两个ObservableCollection<Model> ,每个模型都有10个属性,并且在开始时两个集合中大约有30个对象。 They basicaly work like this: initialy there are saved the same objects in both OCs, where one is the original and the other one is where changes are happening. 他们的工作基本上是这样的:最初,在两个OC中都保存了相同的对象,其中一个是原始对象,另一个是发生更改的对象。 Basicaly I would need the first one just to see if changes have been made to compare the values. 基本上,我需要第一个只是为了查看是否已进行比较以比较这些值。 So far I have come up with 到目前为止,我已经提出了

list1.SequenceEquals(list2);

but this only works if i add a new object, it does not recognize changes in the actual properties. 但这仅在我添加新对象时有效,它无法识别实际属性中的更改。 Is there a fast way this could be done or I need to do foreach for every object and compare individual properties one by one? 有没有一种快速的方法可以完成此操作,或者我需要为每个对象做一次foreach并逐一比较各个属性? Because there may be more than 30 objects to compare values. 因为可能有30多个对象要比较值。 Thanks. 谢谢。

I think you can compare them defining a custom IEqualityComparer<T> , and using the overload of IEnumerable.SequenceEquals that supports a custom comparer: Enumerable.SequenceEqual<TSource> Method (IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>) more info about it here: http://msdn.microsoft.com/it-it/library/bb342073(v=vs.110).aspx 我认为您可以将它们定义为自定义IEqualityComparer<T>并使用支持自定义比较器的IEnumerable.SequenceEquals的重载进行比较: Enumerable.SequenceEqual<TSource> Method (IEnumerable<TSource>, IEnumerable<TSource>, IEqualityComparer<TSource>)有关此信息的更多信息,请访问: http : //msdn.microsoft.com/it-it/library/bb342073(v=vs.110).aspx

I'll post here an usage example from that page in case it goes missing: 如果丢失,我将在此处发布该页面的用法示例:

Here is how to define a IEqualityComparer<T> 这是如何定义IEqualityComparer<T>

public class Product
{
    public string Name { get; set; }
    public int Code { get; set; }
}

// Custom comparer for the Product class
class ProductComparer : IEqualityComparer<Product>
{
    // Products are equal if their names and product numbers are equal.
    public bool Equals(Product x, Product y)
    {

        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the products' properties are equal.
        return x.Code == y.Code && x.Name == y.Name;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Product product)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(product, null)) return 0;

        //Get hash code for the Name field if it is not null.
        int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

        //Get hash code for the Code field.
        int hashProductCode = product.Code.GetHashCode();

        //Calculate the hash code for the product.
        return hashProductName ^ hashProductCode;
    }

}

Here's how to use it: 使用方法如下:

    Product[] storeA = { new Product { Name = "apple", Code = 9 }, 
                           new Product { Name = "orange", Code = 4 } };

    Product[] storeB = { new Product { Name = "apple", Code = 9 }, 
                           new Product { Name = "orange", Code = 4 } };

    bool equalAB = storeA.SequenceEqual(storeB, new ProductComparer());

    Console.WriteLine("Equal? " + equalAB);

    /*
        This code produces the following output:

        Equal? True
    */

Is there a fast way this could be done or I need to do foreach for every object and compare individual properties one by one? 有没有一种快速的方法可以完成此操作,或者我需要为每个对象做一次foreach并逐一比较各个属性?

If by "fast" you mean "performant" then comparing property-by property is probably the fastest way. 如果用“快速”表示“性能”,则逐个属性比较可能是最快的方法。 If by "fast" you mean "less code to write" then you could use reflection to loop through the properties and compare the values of each item. 如果用“快速”表示“编写更少的代码”,则可以使用反射来遍历属性并比较每个项目的值。

Note that you'll probably spend more time researching, writing, and debugging the reflection algorithm that you would just hand-coding the property comparisons. 请注意,您可能将花费更多的时间来研究,编写和调试反射算法,而您只需手工编码属性比较即可。

A simple way to use the built-in Linq methods would be do define an IEqualityComparer<Model> that defines equality of two Model objects: 使用内置Linq方法的一种简单方法是定义一个IEqualityComparer<Model> ,它定义两个Model对象的相等性:

class ModelEqualityComparer : IEqualityComparer<Model>
{

    public bool Equals(Model m1, Model m2)
    {

        if(m1 == null || 2. == null)
            return false;

        if (m1.Prop1 == m2.Prop1 
         && m1.Prop2 == m2.Prop2
         && m1.Prop3 == m2.Prop3
            ...
           )
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    public int GetHashCode(Model m)
    {
        int hCode = m.Prop1.GetHashCode();
        hCode = hCode * 23 + ^ m.Prop2.GetHashCode();
        hCode = hCode * 23 + ^ m.Prop32.GetHashCode();
        ...

        return hCode;
    }

}

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

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