C#列表包含项目
我有一类名为ACCESSOIRE:C#列表包含项目
class accessoire
{
public int value1 { get; set; }
public string Value2 { get; set; }
}
然后我有一个产品
List<accessoire> accessoires
的列表,我有一个用户界面,其中用户挑选他从希望的产品一个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é !");
}
}
这不是工作K,但是当我将其更改为:
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 !");
}
}
它的工作原理,但我'仍然不知道为什么第一个代码does not工作也不断加入该项目的名单?以其他方式.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()
返回错误的项目时没有得到结果的问题。
您可以通过覆盖Equals
替代Cart
,但我不推荐它。它可以在以后进行调试。
只实现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);
}
}
除非[另有说明](https://msdn.microsoft.com/en-us/library/bb339118(v = vs.110))。aspx),'Contains'使用“默认比较器”,对于类只是[检查查看对象是否是同一个引用](https://msdn.microsoft.com/zh-cn/library/system.object .referenceequals(v = vs.110)的.aspx)。 – stuartd
我的猜测是传入的'Accessoire'对象不完整。您应该在某个地方列出所有产品的列表,并使用传入的ID获取完整对象并将该完整对象添加到购物车。 – nurdyguy
什么是购物车?这些与你的'accessoire'课程有什么关系? – krillgar