[英]c# List contain Item
我有一个名为accessoire的类:
class accessoire
{
public int value1 { get; set; }
public string Value2 { get; set; }
}
然后我有该产品的清单
List<accessoire> accessoires
我有一个UI,用户可以在其中从DataGridview中选择他想要的产品,并在他选择它时启动一个事件,将该项目添加到列表中:
private void ProductBrowser_OnItemAdded(Accessoire item)
{
if (Cart.Contains(item))
{
MessageBox.Show("Produit deja ajoutée au panier ! ");
}
else
{
Cart.Add(item);
ProductView.Rows.Add(item.Ref, item.Name, Function.CatName(item.Cat), item.SellPrice, "1", Convert.ToDouble(item.SellPrice) * Convert.ToDouble(item.QtetoSell));
TotalPriceSet();
MessageBox.Show("Produit Ajouté !");
}
}
这不起作用,但是当我将其更改为:
private void ProductBrowser_OnItemAdded(Accessoire item)
{
var InList = Cart.Find(product => product.Ref == item.Ref);
if (Cart.Contains(InList))
{
MessageBox.Show("Product already in list ! ");
}
else
{
Cart.Add(item);
ProductView.Rows.Add(item.Ref, item.Name, Function.CatName(item.Cat), item.SellPrice, "1", Convert.ToDouble(item.SellPrice) * Convert.ToDouble(item.QtetoSell));
TotalPriceSet();
MessageBox.Show("product added !");
}
}
它可以工作,但是我仍然想知道为什么第一个代码不起作用,它总是将该项目添加到列表中? 以其他方式.Contains()
方法如何工作? 它会检查什么以了解该项目是否存在或列表中没有?
之所以没有在列表中找到该对象,是因为它是一个引用比较,它比较对象的实例而不是值。 您可以有两个类的实例,它们的属性具有相同的值,但是如果将它们进行比较,它们将不相等:
accessoire item1 = new accessoire();
item1.value1 = 1;
item1.value2 = "one";
accessoire item2 = new accessoire();
item2.value1 = 1;
item2.value2 = "one";
if(item1 == item2) MessageBox.Show("Same");
else MessageBox.Show("Different");
当您从列表中选择要比较的项目时,您将拉出确实存在于列表中的特定实例。
您需要实现accessoire的Equals方法,以正确比较其中的所有属性/字段。 Equals的默认实现使用ReferenceEquals,它仅在两个实例实际上相同时才起作用。
if (Cart.Contains(item))
通过平等匹配。
如果object.Equals(T)
不满足,它将失败。 这意味着最小的更改,即使字符串中的空格也将返回false。 如果您有两个相同类的实例,您也会得到错误的结果。 所包含的内容必须完全指代item
。
var InList = Cart.Find(product => product.Ref == item.Ref)
是按属性匹配。 这意味着只要.Ref匹配,产品/项目的其他属性都可以不同。 我认为Ref是主键,这就是为什么在Find()
返回错误项目的结果中没有出现问题的原因。
您可以通过覆盖Cart
Equals
来解决差异,但是我不建议这样做。 它可以使以后进行调试。
只需实现equals方法
// override object.Equals
public override bool Equals(object obj)
{
//
// See the full list of guidelines at
// http://go.microsoft.com/fwlink/?LinkID=85237
// and also the guidance for operator== at
// http://go.microsoft.com/fwlink/?LinkId=85238
//
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var data = (accessoire)obj;
return this.Ref.Equals(data.Ref);
}
// override object.GetHashCode
public override int GetHashCode()
{
return this.Ref.GetHashCode()
}
您正在进行引用比较,而第一个示例中的引用不匹配,但第二个示例中的引用却匹配。 您可能想要进行相等比较。 两个对象的值是否相同?
下面是您的类,该类使用用于相等比较的各种方法来实现。 您只需要修改它们以适合您的目的。
// IEquatable<T> provides typed equality comparing
class accessoire : IEquatable<accessoire>
{
public int Value1 { get; set; }
public string Value2 { get; set; }
// you can override Equals.
public override bool Equals(object obj)
{
return this.Equals(obj as accessoire);
}
// this comes from IEquatable<T>
public bool Equals(accessoire other)
{
if (ReferenceEquals(null, other))
{
return false;
}
// return the comparison that makes them equal.
return
this.Value1.Equals(this.Value1) &&
this.Value2.Equals(this.Value2);
}
public override int GetHashCode()
{
unchecked
{
int hash = 37;
hash *= 23 + this.Value1.GetHashCode();
hash *= 23 + this.Value2.GetHashCode();
return hash;
}
}
// allows you to check equality with the == operator
public static bool operator ==(accessoire left, accessoire right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if ((oject)left == null || (object)right == null)
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(accessoire left, accessoire right)
{
return !left.Equals(right);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.