C#列表重复项

3
我想知道为什么当我尝试不将重复的对象添加到列表中时,它仍然被添加了。
if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
    thePreviousList.Add(thePreviousItem);
}

例如,对于先前的项 id = 1 和名称 = test,如果我有另一个具有相同 id 和相同名称的对象,则仍将其添加...

也许你想使用 Dictionary(Of TKey, TValue) 而不是列表。 - Conrad Frix
5个回答

5

您需要正确实现要添加到列表中的对象的Equals方法。为了确定列表是否已包含传递的对象,Contains方法使用Equals


我该怎么做才能避免在列表中添加重复对象?而且不能使用equals方法? - Kiwimoisi
3
为什么不想使用Equals方法?它是最简单的做法。 - Nikola Anusev
@Emged 你可以使用不允许重复的集合(例如 HashSet<T>),并提供一个比较器,或者编写自己的 Contains 方法,使用自定义比较器在列表中搜索项目。 - Servy

4

根据文档:

此方法使用默认的相等比较器来确定相等性,该比较器由对象对 T 类型(列表中的值类型)实现的 IEquatable(Of T).Equals 方法定义。

如果您没有实现 IEquatable<T>.Equals,它将使用默认的引用相等性。或者,您已经实现了 IEquatable<T>.Equals 但是没有正确实现。

例如,上一个条目的 id = 1 和 name = 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>


你不一定需要实现 IEquatable<T>,只要重写 Equals 就足够了,因为默认的比较器会在没有实现 IEquatable<> 的情况下调用 Equals - Igor Korkhov

4

如果您不想覆盖Equals,可以使用LINQ检查是否已经存在具有相同ID和名称(不一定是相同的对象)的对象:

if (thePreviousList.Any(item => item.ID == thePreviousItem.ID
                             && item.Name == thePreviousItem.Name)) 
{ 
} 
else 
{ 
    thePreviousList.Add(thePreviousItem); 
} 

2

从您对其他答案的评论中可以看出,您不想覆盖 Equals

您可以选择这样做:

if (thePreviousList.Any(item => thePreviousItem.id == item.id && thePreviousItem.name == item.name))
{

}
else
{
    thePreviousList.Add(thePreviousItem);
}

1

因为 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();
}

那么,如果有重复项,我该怎么做才能不将对象添加到列表中呢? - Kiwimoisi
1
@Emged - 请看更新(尽管我看到你下面的评论说不使用Equals - 这总是让我困惑...为什么你想以任何方式都不是正确的方式去做某事呢?) - Jamiec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接