如何比较两个对象列表?

时间:2015-11-15 08:44:04

标签: c#

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

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

客户存储在List CustomersA中,另外我还有一个List CustomersB。 CustomersB是" Truth"。

我需要找出

  • CustomersB中的客户,但不是CustomersA中的客户(通过CustomerID)
  • CustomersA中的客户,但不是CustomersB中的客户(按客户ID)(与上述相同)
  • CustomersB中的客户也在CustomerA中具有相同的CustomerID但客户名称不同

我怎样才能用C#实现这个目标?

2 个答案:

答案 0 :(得分:4)

您应该使用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但客户名称不同

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

答案 1 :(得分:2)

如果您计划在多个地方进行这些比较,您还可以创建自定义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>传递给它,并且您将被绑定。