.Contains () в списке объектов пользовательских классов - PullRequest
78 голосов
/ 13 апреля 2010

Я пытаюсь использовать функцию .Contains() в списке пользовательских объектов

Это список:

List<CartProduct> CartProducts = new List<CartProduct>();

И CartProduct:

public class CartProduct
{
    public Int32 ID;
    public String Name;
    public Int32 Number;
    public Decimal CurrentPrice;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="ID">The ID of the product</param>
    /// <param name="Name">The name of the product</param>
    /// <param name="Number">The total number of that product</param>
    /// <param name="CurrentPrice">The currentprice for the product (1 piece)</param>
    public CartProduct(Int32 ID, String Name, Int32 Number, Decimal CurrentPrice)
    {
        this.ID = ID;
        this.Name = Name;
        this.Number = Number;
        this.CurrentPrice = CurrentPrice;
    }
    public String ToString()
    {
        return Name;
    }
}

Поэтому я пытаюсь найти аналогичный продукт в списке:

if (CartProducts.Contains(p))

Но он игнорирует похожие продукты, и я, кажется, не знаю, что он проверяет - идентификатор? или это все?

Заранее спасибо! :)

Ответы [ 6 ]

122 голосов
/ 13 апреля 2010

Если вы используете .NET 3.5 или новее, вы можете использовать методы расширения LINQ для выполнения проверки «содержит» с помощью метода Any:

if(CartProducts.Any(prod => prod.ID == p.ID))

Это проверит наличие продукта в CartProducts с идентификатором, совпадающим с идентификатором p. Вы можете поместить любое логическое выражение после =>, чтобы выполнить проверку.

Это также дает преимущество работы с запросами LINQ-to-SQL, а также с запросами в памяти, где Contains нет.

104 голосов
/ 13 апреля 2010

Вам нужно реализовать IEquatable или переопределить Equals() и GetHashCode()

Например:

public class CartProduct : IEquatable<CartProduct>
{
    public Int32 ID;
    public String Name;
    public Int32 Number;
    public Decimal CurrentPrice;

    public CartProduct(Int32 ID, String Name, Int32 Number, Decimal CurrentPrice)
    {
        this.ID = ID;
        this.Name = Name;
        this.Number = Number;
        this.CurrentPrice = CurrentPrice;
    }

    public String ToString()
    {
        return Name;
    }

    public bool Equals( CartProduct other )
    {
        // Would still want to check for null etc. first.
        return this.ID == other.ID && 
               this.Name == other.Name && 
               this.Number == other.Number && 
               this.CurrentPrice == other.CurrentPrice;
    }
}
10 голосов
/ 13 апреля 2010

Проверяет, содержится ли конкретный объект в списке.

Возможно, вам лучше использовать метод Find в списке.

Вот пример

List<CartProduct> lst = new List<CartProduct>();

CartProduct objBeer;
objBeer = lst.Find(x => (x.Name == "Beer"));

Надеюсь, что поможет

Вам также следует взглянуть на LinQ - возможно, это излишне, но, тем не менее, полезно ...

4 голосов
/ 13 апреля 2010

По умолчанию ссылочные типы имеют ссылочное равенство (т.е. два экземпляра равны, только если они являются одним и тем же объектом).

Вам необходимо переопределить Object.EqualsObject.GetHashCode для соответствия), чтобы реализовать собственное равенство. (И это хорошая практика для реализации равенства, ==, оператор.)

0 голосов
/ 24 февраля 2019

Реализация override Equals() и GetHashCode()

public class CartProduct
{
    public Int32 ID;
    ...

    public CartProduct(Int32 ID, ...)
    {
        this.ID = ID;
        ...
    }

    public override int GetHashCode()
    {
        return ID;
    }

    public override bool Equals(Object obj)
        {
            if (obj == null || !(obj is CartProduct))
                return false;
            else
                return GetHashCode() == ((CartProduct)obj).GetHashCode();
        }

}

используется:

if (CartProducts.Contains(p))
0 голосов
/ 13 апреля 2010

Если вы хотите иметь контроль над этим, вам нужно реализовать [IEquatable интерфейс] [1]

[1]: http://This метод определяет равенство с помощью средства сравнения по умолчанию, как это определено реализацией объекта метода IEquatable.Equals для T (тип значений в списке).

...