我很奇怪,为什么当我尝试不加我的对象列表中时,它的复制,它仍然将它添加C#列表中的重复
if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
例如thepreviousitem ID = 1,名称=测试 如果我有另一个对象具有相同的ID和相同的名称它仍然会添加它...
我很奇怪,为什么当我尝试不加我的对象列表中时,它的复制,它仍然将它添加C#列表中的重复
if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
例如thepreviousitem ID = 1,名称=测试 如果我有另一个对象具有相同的ID和相同的名称它仍然会添加它...
如果你不想重载Equals,你可以使用LINQ来检查是否使用相同的ID和名称的对象(这不一定相同对象)已经存在:
if (thePreviousList.Any(item => item.ID == thePreviousItem.ID
&& item.Name == thePreviousItem.Name))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
您需要正确实施Equals
方法对您试图添加到列表中的对象。要确定列表是否已包含传递的对象,Contains
方法使用的是Equals
。
因为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();
}
从文档:
该方法通过使用默认的相等比较确定的平等,由对象的实现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>
。
您不一定需要为了实现'IEquatable
这听起来从您对其他答案的意见,你不想覆盖Equals
。
可以代替做到这一点:
if (thePreviousList.Any(item => thePreviousItem.id == item.id && thePreviousItem.name == item.name))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
也许你想使用词典('TKEY的,TValue)',而不是名单 – 2012-03-29 15:24:00