C#列表重复

时间:2012-03-29 15:17:14

标签: c# asp.net list duplicates

我想知道为什么当我尝试不在列表中添加我的对象时,它仍在添加它

if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
    thePreviousList.Add(thePreviousItem);
}

例如,previousitem id = 1和name = test 如果我有另一个具有相同ID和相同名称的对象,它仍然会添加它......

5 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:4)

来自文档:

  

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

如果您尚未实现IEquatable<T>.Equals,则使用默认值为引用相等性。或者,您实现了IEquatable<T>.Equals但没有正确执行。

  

例如thepreviousitem id = 1 and 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>

答案 2 :(得分:4)

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

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

答案 3 :(得分:2)

根据您对其他答案的评论,您不想覆盖Equals

你可以这样做:

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

}
else
{
    thePreviousList.Add(thePreviousItem);
}

答案 4 :(得分: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();
}