2010-04-13 13 views
66

Estoy tratando de utilizar la función de .Contains() en una lista de objetos personalizados.Contains() en una lista de objetos de clase personalizada

Esta es la lista:

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

Y el 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; 
    } 
} 

así que trato de encontrar un cartproduct similar dentro de la lista:

if (CartProducts.Contains(p)) 

Pero ignora productos de carrito similares y no parece saber qué comprueba: ¿la ID? o todo?

¡Gracias de antemano! :)

Respuesta

92

es necesario implementar IEquatable o anular Equals() y GetHashCode()

Por ejemplo:

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

Gracias Rowland :) –

5

Por defecto, los tipos de referencia tienen igualdad de referencia (es decir, dos instancias son iguales si son el mismo objeto).

Debe sobrescribir Object.Equals (y Object.GetHashCode para que coincida) para implementar su propia igualdad. (Y es entonces una buena práctica para poner en práctica una igualdad, ==, operador.)

+0

¿Por qué anular Object.Equals, lo que podría tener consecuencias en otras partes del código? Para mí, tiene más sentido modificar el código de búsqueda en consecuencia, y no la clase subyacente del objeto que se está buscando ... –

+0

¿Tiene algunos ejemplos de esto, .Find() o anulando el Object.Equals/GetHashCode ? –

+0

@Martin IT estaría muy roto si quisiera que la comparación de dos objetos 'CartProduct' se comporte de manera diferente en diferentes lugares. –

0

Si usted quiere tener control sobre ello, tiene que implementar el [interfaz IEquatable] [1]

[1]: http://This El método determina la igualdad mediante el uso del comparador de igualdad predeterminado, según lo define la implementación del método IEquatable.Equals para T (el tipo de valores en la lista).

10

Se comprueba si el objeto específico está contenido en la lista.

Puede que sea mejor usar el método Buscar en la lista.

He aquí un ejemplo

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

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

Espero que ayude

Usted también debe mirar a LinQ - exageración para este quizá, sino una herramienta útil, no obstante ...

+0

¿cómo puede Linq ser exagerado? –

+0

@MEL - ¿Por qué mezclarse en una consulta y escribir inferencia por algo tan simple? Sin embargo, podría ser más legible para alguien que no esté familiarizado con lamdas ... –

+0

+1 Buen ejemplo claro, que muestra la opción que no se vería afectada por los cambios en otros lugares (es decir, si el método 'Equals()' cambiaba por cualquier razón) –

95

Si está utilizando. NET 3.5 o posterior, puede usar los métodos de extensión LINQ para lograr un control "contiene" con el método de extensión Any:

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

Esto comprobará la existencia de un producto dentro de CartProducts que tenga un ID que coincida con el ID de p. Puede poner cualquier expresión booleana después del => para realizar la verificación.

Esto también tiene la ventaja de trabajar para consultas LINQ-to-SQL así como consultas en memoria, donde Contains no lo hace.

Cuestiones relacionadas