我需要比较两个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
我需要添加一个条件,即在比较两个列表时,请忽略“名称”字段的大小写。
答案 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
快速检查一个对象是否等于另一个对象。这就是为什么您的类应该重写Equals
和GetHashCode
(总是一起)以支持在基于集合的集合(例如HashSet<T>
或Dictionary<TKey, TValue>
)中使用。否则,您将使用System.Object
中的版本,该版本仅比较引用而不是属性。
答案 1 :(得分:6)
如果您想用自己的规则比较相等性,让我们实现Equals
和GetHashCode
方法:
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