2012-03-29 61 views
3

我很奇怪,为什么当我尝试不加我的对象列表中时,它的复制,它仍然将它添加C#列表中的重复

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

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

+0

也许你想使用词典('TKEY的,TValue)',而不是名单 – 2012-03-29 15:24:00

回答

4

如果你不想重载Equals,你可以使用LINQ来检查是否使用相同的ID和名称的对象(这不一定相同对象)已经存在:

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

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

+0

我能做些什么,然后以不添加对象列表中是否有重复?没有使用equals方法? – Kiwimoisi 2012-03-29 15:21:19

+3

为什么你不想使用'Equals'方法?这是最简单的事情。 – 2012-03-29 15:23:31

+0

@Emged您可以使用不会接受重复的集合(即集合,例如HashSet )并提供比较器,也可以编写自己的Contains方法来搜索列表以查找使用自定义比较器的项目。 – Servy 2012-03-29 15:26:50

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(); 
} 
+0

那么如果有重复的话,不要在列表中添加对象,我该怎么办? – Kiwimoisi 2012-03-29 15:20:38

+1

@Emged - 查看更新(尽管我在下面看到您的评论关于不使用Equals - 这总是让我感到困惑......您为什么还想用除* right *之外的其他方式做点什么?) – Jamiec 2012-03-29 15:23:28

4

从文档:

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

如果您还没有实施IEquatable<T>.Equals,它使用默认的引用相等。或者,您实现了IEquatable<T>.Equals,但没有正确执行。

例如thepreviousitem ID = 1,名称=测试,如果我有相同的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>

+0

您不一定需要为了实现'IEquatable ',覆盖'Equals'就足够了,因为如果没有实现IEquatable <>',默认比较器会调用Equals。 – 2012-03-29 15:32:16

2

这听起来从您对其他答案的意见,你不想覆盖Equals

可以代替做到这一点:

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

} 
else 
{ 
    thePreviousList.Add(thePreviousItem); 
}