繁体   English   中英

c#列表包含项目

[英]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.

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