2017-01-09 183 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); 
    } 
}