我想知道为什么当我尝试不在列表中添加我的对象时,它仍在添加它
if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
thePreviousList.Add(thePreviousItem);
}
例如,previousitem id = 1和name = test 如果我有另一个具有相同ID和相同名称的对象,它仍然会添加它......
答案 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();
}