根据条件比较两个对象

use*_*636 4 c# linq string

我需要比较两个,List<object>但是在比较具有“字符串”值的属性时,我不希望区分大小写

我有一堂课:

class User
{
    public int Id { get;set; }
    public string name { get;set; }
}
Run Code Online (Sandbox Code Playgroud)

我有2个清单List<User> olduserList<User> newuser。我需要比较两个列表,但是在比较时,我应该忽略“名称”字段的大小写敏感性,并获取olduser不属于的值的一部分newuser

List<User> obsoleteUsers = olduser.Except(newuser).ToList();
Run Code Online (Sandbox Code Playgroud)

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

Tim*_*ter 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

List<User> obsoleteUsers = olduser
    .Except(newuser, new UserNameComparer(StringComparer.InvariantCultureIgnoreCase))
    .ToList();
Run Code Online (Sandbox Code Playgroud)

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

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


Dmi*_*nko 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;
  }
Run Code Online (Sandbox Code Playgroud)

那你可以Except照常放