根据条件比较两个对象

时间:2019-07-18 07:24:16

标签: c# string linq

我需要比较两个User u = User.getById(id, false) def email = u.getProperty(Mailer.UserProperty.class) print email.getAddress() ,但是在比较具有“字符串”值的属性时我不希望区分大小写比较

我有一堂课

List<object>

我有2个列表class User { public int Id { get;set; } public string name { get;set; } } List<User> olduser。我需要比较两个列表,但是在比较时,我应该忽略“名称”字段的区分大小写,并获取List<User> newuser中的值,而不是olduser中的值的一部分。

newuser

我需要添加一个条件,即在比较两个列表时,请忽略“名称”字段的大小写。

2 个答案:

答案 0 :(得分:7)

您可以使用自定义IEqualityComparer<T>

class UserNameComparer : IEqualityComparer<User>
{
    public UserNameComparer(StringComparer comparer)
    {
        if (comparer == null) throw new ArgumentNullException(nameof(comparer));
        this.Comparer = comparer;
    }

    public StringComparer Comparer { get; }

    public bool Equals(User x, User y)
    {
        if (x == null || y == null) return true;
        return Comparer.Equals(x.name, y.name);
    }

    public int GetHashCode(User obj)
    {
        return Comparer.GetHashCode(obj?.name);
    }
}

您在Except(或其他LINQ方法)中使用它:

List<User> obsoleteUsers = olduser
    .Except(newuser, new UserNameComparer(StringComparer.InvariantCultureIgnoreCase))
    .ToList();

通过这种方式,您可以针对不同的需求实现多个比较器,而无需更改原始类及其标识重复项的方式(例如,通过ID属性)。

请注意,Except(以及其他基于集合的方法,例如Distinct)使用GetHashCode快速检查一个对象是否等于另一个对象。这就是为什么您的类应该重写EqualsGetHashCode(总是一起)以支持在基于集合的集合(例如HashSet<T>Dictionary<TKey, TValue>)中使用。否则,您将使用System.Object中的版本,该版本仅比较引用而不是属性。

答案 1 :(得分:6)

如果您想用自己的规则比较相等性,让我们实现EqualsGetHashCode方法:

  class User : IEquatable<User> {
    // Dangerous practice: Id (and name) usually should be readonly:
    // we can put instance into, say, dictionary and then change Id loosing the instance 
    public int Id { get; set; }
    public string name { get; set; }

    public bool Equals(User other) {
      if (null == other)
        return false;

      return  
        Id == other.Id && 
        string.Equals(name, other.name, StringComparison.OrdinalIgnoreCase);
    }

    public override bool Equals(object obj) => Equals(obj as User);

    public override int GetHashCode() => Id;
  }

然后您可以照常放Except