简体   繁体   English

c#列表包含项目

[英]c# List contain Item

I have a class named accessoire : 我有一个名为accessoire的类:

   class accessoire 
    {
       public int value1 { get; set; }
        public string Value2 { get; set; }    
    }

then i have a List of that product 然后我有该产品的清单

List<accessoire> accessoires

And i have an UI where the user pick the product he wants from a DataGridview and when he selected it launch an event that add this item to the list : 我有一个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é !");
        }

    }

this doesnt work , but when i change it to : 这不起作用,但是当我将其更改为:

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

    }

it works , but i'am still wondering why the first code doesnt work it keep adding that item to the list ? 它可以工作,但是我仍然想知道为什么第一个代码不起作用,它总是将该项目添加到列表中? in other way how does the method .Contains() works ? 以其他方式.Contains()方法如何工作? what does it check to know if the item is or the list on not ? 它会检查什么以了解该项目是否存在或列表中没有?

The reason it doesn't find the object in the list is because it is a reference comparison, comparing the instances of the object, not the values. 之所以没有在列表中找到该对象,是因为它是一个引用比较,它比较对象的实例而不是值。 You can have two instances of your class with the same values in their properties, but if you compare them, they are not equal: 您可以有两个类的实例,它们的属性具有相同的值,但是如果将它们进行比较,它们将不相等:

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

When you select the item from the list to compare with, you are pulling the specific instance, which does exist in the list. 当您从列表中选择要比较的项目时,您将拉出确实存在于列表中的特定实例。

You need to implement the Equals method of accessoire to properly compare all properties/fields in it. 您需要实现accessoire的Equals方法,以正确比较其中的所有属性/字段。 The default implementation of Equals uses ReferenceEquals, which only works if the two instances are in fact the same. Equals的默认实现使用ReferenceEquals,它仅在两个实例实际上相同时才起作用。

if (Cart.Contains(item)) 

is matching by equality. 通过平等匹配。
If object.Equals(T) is not satisified, it will fail. 如果object.Equals(T)不满足,它将失败。 That means the smallest change, even whitespace in a string, will return false. 这意味着最小的更改,即使字符串中的空格也将返回false。 You'll also get a false result if you have two instances of the same class. 如果您有两个相同类的实例,您也会得到错误的结果。 Contains must refer to exactly item . 所包含的内容必须完全指代item

var InList = Cart.Find(product => product.Ref == item.Ref) is a match by property. var InList = Cart.Find(product => product.Ref == item.Ref)是按属性匹配。 This means that other properties of the product/item can all be different, as long as .Ref matches. 这意味着只要.Ref匹配,产品/项目的其他属性都可以不同。 I presume Ref is a primary key, which is why you're not getting problems in your result where Find() returns the wrong item. 我认为Ref是主键,这就是为什么在Find()返回错误项目的结果中没有出现问题的原因。

You can get around the difference by overriding Equals for Cart , but I don't recommend it. 您可以通过覆盖Cart Equals来解决差异,但是我不建议这样做。 It can make debugging hell later. 它可以使以后进行调试。

Just implement the equals method 只需实现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()
    }

You were doing reference compare and the references don't match in your first example, but do in your second. 您正在进行引用比较,而第一个示例中的引用不匹配,但第二个示例中的引用却匹配。 You probably want to do equality comparison. 您可能想要进行相等比较。 Are the values of both objects the same. 两个对象的值是否相同?

Below is your class implemented with the various methods used for equality comparing. 下面是您的类,该类使用用于相等比较的各种方法来实现。 You would just need to modify them to suit your purposes. 您只需要修改它们以适合您的目的。

// 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM