2010-04-13 2 views
66

Я пытаюсь использовать функцию .Contains() в списке пользовательских объектов.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; 
    } 
} 

Так я пытаюсь найти аналогичную cartproduct в пределах списка:

if (CartProducts.Contains(p)) 

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

Заранее благодарен! :)

ответ

92

Вы должны реализовать 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; 
    } 
} 
+0

Спасибо Rowland :) –

5

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

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

+0

Зачем стоит переопределять Object.Equals, который может иметь последствия в другом месте кода? Для меня имеет смысл изменить соответствующий код поиска, а не базовый класс объекта, который выполняется поиск ... –

+0

У вас есть некоторые примеры этого .Find() или переопределение Object.Equals/GetHashCode ? –

+0

@Martin IT будет очень сломан, если вы хотите, чтобы сравнение двух объектов CartProduct' велось по-разному в разных местах. –

0

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

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

10

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

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

Вот пример

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

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

Надежда, что помогает

Вы также должны смотреть на Linq - избыточна для этого может быть, но полезный инструмент, тем не менее ...

+0

как может Linq когда-либо быть overkill? –

+0

@MEL - Зачем смешиваться в запросе и вводить вывод для чего-то такого простого? Тем не менее, это может быть более читаемым для кого-то, не знакомого с lamdas ... –

+0

+1 Хороший пример, который показывает вариант, на который не повлияли бы изменения в другом месте (т.е. если метод 'Equals()' был изменен для любой причины) –

95

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

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

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

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