.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;
}
}
Поэтому я пытаюсь найти аналогичный продукт в списке:
if (CartProducts.Contains(p))
Но он игнорирует похожие продукты, и я, кажется, не знаю, что он проверяет - идентификатор? или это все?
Заранее спасибо!:)
6 ответов
Вам необходимо реализовать 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;
}
}
Если вы используете.NET 3.5 или новее, вы можете использовать методы расширения LINQ, чтобы выполнить проверку "содержит" с помощью Any
метод расширения:
if(CartProducts.Any(prod => prod.ID == p.ID))
Это проверит наличие продукта в CartProducts
который имеет идентификатор, совпадающий с идентификатором p
, Вы можете поставить любое логическое выражение после =>
выполнить проверку на.
Это также дает преимущество работы с запросами LINQ-to-SQL, а также с запросами в памяти, где Contains
не делает.
Он проверяет, содержится ли конкретный объект в списке.
Возможно, вам лучше использовать метод Find в списке.
Вот пример
List<CartProduct> lst = new List<CartProduct>();
CartProduct objBeer;
objBeer = lst.Find(x => (x.Name == "Beer"));
надеюсь, это поможет
Вам также следует взглянуть на LinQ - возможно, это излишне, но, тем не менее, полезно...
По умолчанию ссылочные типы имеют ссылочное равенство (т.е. два экземпляра равны, только если они являются одним и тем же объектом).
Вы должны переопределить Object.Equals
(а также Object.GetHashCode
соответствовать), чтобы реализовать свое собственное равенство. (И тогда хорошая практика для реализации равенства, ==
, оператор.)
Вам нужно создать объект из вашего списка, например:
List<CartProduct> lst = new List<CartProduct>();
CartProduct obj = lst.Find(x => (x.Name == "product name"));
Этот объект получает искомое значение при поиске по их свойствам: x.name
Затем вы можете использовать методы списка, такие как Contains или Remove
if (lst.Contains(obj))
{
lst.Remove(obj);
}
Воплощать в жизнь 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))
Если вы хотите иметь контроль над этим, вам нужно реализовать [IEquatable интерфейс] [1]
[1]: http: // Этот метод определяет равенство с помощью средства сравнения по умолчанию, как это определено реализацией объекта метода IEquatable.Equals для T (тип значений в списке).