2017-01-09 134 views
0

我有一类名为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()方法如何工作?它是什么检查知道该项目是否或列表不是?

+1

除非[另有说明](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

+0

我的猜测是传入的'Accessoire'对象不完整。您应该在某个地方列出所有产品的列表,并使用传入的ID获取完整对象并将该完整对象添加到购物车。 – nurdyguy

+0

什么是购物车?这些与你的'accessoire'课程有什么关系? – krillgar

回答

4

它在列表中找不到对象的原因是因为它是参考比较,比较对象的实例而不是值。你可以用它们的属性相同的值类的两个实例,但如果你比较他们,他们是不相等的:

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"); 

当您从列表中选择的项目有,你拉来比较具体的实例,它存在于列表中。

0

您需要实现Accessoire的Equals方法以正确比较其中的所有属性/字段。 Equals的默认实现使用ReferenceEquals,它只在两个实例相同时才有效。

0
if (Cart.Contains(item)) 

通过平等匹配。
如果object.Equals(T)不合格,它将失败。这意味着最小的变化,即使是字符串中的空格,也会返回false。如果你有两个同一类的实例,你也会得到一个错误的结果。包含必须完全参照item

var InList = Cart.Find(product => product.Ref == item.Ref)是属性匹配。这意味着只要.Ref匹配,产品/项目的其他属性都可以不同。我认为Ref是主键,这就是为什么你在Find()返回错误的项目时没有得到结果的问题。

您可以通过覆盖Equals替代Cart,但我不推荐它。它可以在以后进行调试。

0

只实现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() 
    } 
0

你正在做参考比较和参考文献没有在你的第一个例子匹配,但在你的第二个做的。你可能想要做平等比较。两个对象的值是否相同。

下面是你的类实现与用于相等比较的各种方法。你只需要修改它们以适合你的目的。

// 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); 
    } 
}