繁体   English   中英

如何比较两个对象列表?

[英]How to compare two lists of objects?

我在C#中有一个简单的类:

public class Customer
{
    public string CustomerName { get; set; }
    public int CustomerId { get; set; }
    public int RegionId { get; set; }
}

客户存储在列表客户A中,另外我还有一个列表客户B。 客户B是“真相”。

我需要找出

  • 客户B中的客户,而不是客户A中的客户(按客户ID)
  • 客户A中的客户,而不是客户B中的客户(按客户ID)(与上述相同)
  • 客户B中的客户在客户A中也具有相同的客户ID,但客户名不同

我如何使用C#实现呢?

您应该使用LINQ进行数据设置操作:

•CustomersB中的客户,而不是CustomersA中的客户(按CustomerID)

var query = customersB.Where(cB => !customersA.Any(cA => cA.Id == cB.Id)).ToList();

•CustomersA中的客户,而不是CustomersB中的客户(按CustomerID)

var query = customersA.Where(cA => !customersB.Any(cB => cB.Id == cA.Id)).ToList();

•CustomersB中的客户在CustomerA中也具有相同的CustomerID,但具有不同的CustomerName

var query = customersB.Where(cB => customersA.Any(cA => cA.Id == cB.Id 
                                                  && cA.CustomerName != cB.CustomerName))
                      .ToList();

如果您打算在多个地方进行这些比较,则还可以创建一个自定义的EqualityComparer<Customer>并在需要的地方重复使用它们。

这是两个比较器的示例,一个基于ID,另一个基于ID和Name。 在此示例中,我假设一个客户ID是唯一的:

public sealed class CustomerByIdEqualityComparer : IEqualityComparer<Customer>
{
    public bool Equals(Customer x, Customer y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return x.CustomerId == y.CustomerId;
    }

    public int GetHashCode(Customer obj)
    {
        return obj.CustomerId;
    }
}

public sealed class CustomerByIdAndNameEqualityComparer : IEqualityComparer<Customer>
{
    public bool Equals(Customer x, Customer y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return !string.Equals(x.CustomerName, y.CustomerName) &&
                x.CustomerId == y.CustomerId;
    }

    public int GetHashCode(Customer obj)
    {
        return obj.CustomerId;
    }
}

然后使用Enumerable.Except消耗它们:

var comparerById = new CustomerByIdEqualityComparer();
var comparerByIdAndName = new CustomerByIdAndNameEqualityComparer();

var customerARelativeComplement = customersA.Except(customersB, comparerById);
var customerBRelativeComplement = customersB.Except(customersA, comparerById);
var customersBRelativeComplementByName = customersB
                                         .Except(customersA, comparerByIdAndName);

如果使用大型集,请考虑使用HashSet<T>进行过滤。 唯一的问题是您只能将一个EqualityComparer<T>传递给它,并且您将被绑定到它。

暂无
暂无

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

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