我需要比较两个,List<object>
但是在比较具有“字符串”值的属性时,我不希望区分大小写。
我有一堂课:
class User
{
public int Id { get;set; }
public string name { get;set; }
}
Run Code Online (Sandbox Code Playgroud)
我有2个清单List<User> olduser
和List<User> newuser
。我需要比较两个列表,但是在比较时,我应该忽略“名称”字段的大小写敏感性,并获取olduser
不属于的值的一部分newuser
。
List<User> obsoleteUsers = olduser.Except(newuser).ToList();
Run Code Online (Sandbox Code Playgroud)
我需要添加一个条件,即在比较两个列表时,请忽略“名称”字段的大小写。
您可以使用自定义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
快速检查一个对象是否等于另一个。这就是为什么您的类应该重写Equals
和GetHashCode
(总是一起)以支持在基于集合的集合(如HashSet<T>
或Dictionary<TKey, TValue>
)中使用。否则,您将使用System.Object
仅比较参考而非属性的版本。
如果要比较自己的规则是否相等,让我们实现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;
}
Run Code Online (Sandbox Code Playgroud)
那你可以Except
照常放
归档时间: |
|
查看次数: |
122 次 |
最近记录: |