C# 列表重复
本文关键字:列表 | 更新日期: 2023-09-27 18:29:20
我想知道为什么当我尝试在重复时不将我的对象添加到列表中时,它仍然在添加它
if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
例如,上一个项 id = 1 和名称 = 测试如果我有另一个具有相同 id 和相同名称的对象,它仍然会添加它......
您需要
在尝试添加到列表中的对象上正确实现Equals
方法。若要确定列表是否已包含传递的对象,Contains
方法使用 Equals
。
如果不想重写 Equals,可以使用 LINQ 检查是否已存在具有相同 ID 和名称的对象(不一定是相同的对象(:
if (thePreviousList.Any(item => item.ID == thePreviousItem.ID
&& item.Name == thePreviousItem.Name))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
从文档中:
此方法通过使用默认相等比较器来确定相等性,该比较器由对象的 IEquatable(Of T( 实现所定义。T 的等于方法(列表中的值的类型(。
如果您尚未实现 IEquatable<T>.Equals
,则使用默认值,即引用相等性。或者,您实现了IEquatable<T>.Equals
,但没有正确执行。
例如,上一个项目 id = 1 和名称 = test 如果我有另一个具有相同 id 和相同名称的对象,它仍然会添加它......
你需要类似的东西
class Foo : IEquatable<Foo> {
public int Id { get; private set; }
public string Name { get; private set; }
public Foo(int id, string name) {
this.Id = id;
this.Name = name;
}
public bool Equals(Foo other) {
return this.Id == other.Id && this.Name == other.Name;
}
}
最后,如果检查重复项是您要做很多的事情,那么您不应该使用 List<T>
.您应该使用 HashSet<T>
.
从您对其他答案的评论中听起来您不想覆盖Equals
.
您可以改为执行以下操作:
if (thePreviousList.Any(item => thePreviousItem.id == item.id && thePreviousItem.name == item.name))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
因为List<>.Contains
正在检查引用而不检查列表中对象的属性。
为此,您应该覆盖Equals
,并且为了最佳实践,也覆盖GetHashCode
。规则应该是当Equals
返回 true 时,应返回相同的哈希代码。
像下面这样的东西就足够了:
public override bool Equals(object obj)
{
var i = obj as YourType;
if(i == null) return false;
return i.Id == this.Id && i.Name == this.Name;
}
public override int GetHashCode()
{
return this.Id.GetHashCode() ^ this.Name.GetHashCode();
}