.Contains() on a list of custom class objects

151,407

Solution 1

You need to implement IEquatable or override Equals() and GetHashCode()

For example:

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

Solution 2

If you are using .NET 3.5 or newer you can use LINQ extension methods to achieve a "contains" check with the Any extension method:

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

This will check for the existence of a product within CartProducts which has an ID matching the ID of p. You can put any boolean expression after the => to perform the check on.

This also has the benefit of working for LINQ-to-SQL queries as well as in-memory queries, where Contains doesn't.

Solution 3

It checks to see whether the specific object is contained in the list.

You might be better using the Find method on the list.

Here's an example

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

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

Hope that helps

You should also look at LinQ - overkill for this perhaps, but a useful tool nonetheless...

Solution 4

By default reference types have reference equality (i.e. two instances are only equal if they are the same object).

You need to override Object.Equals (and Object.GetHashCode to match) to implement your own equality. (And it is then good practice to implement an equality, ==, operator.)

Solution 5

You need to create a object from your list like:

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

CartProduct obj = lst.Find(x => (x.Name == "product name"));

That object get the looked value searching by their properties: x.name

Then you can use List methods like Contains or Remove

if (lst.Contains(obj))
{
   lst.Remove(obj);
}
Share:
151,407

Related videos on Youtube

Jan Johansen
Author by

Jan Johansen

Updated on July 08, 2022

Comments

  • Jan Johansen
    Jan Johansen almost 2 years

    I'm trying to use the .Contains() function on a list of custom objects

    This is the list:

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

    And the 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;
        }
    }
    

    So i try to find a similar cartproduct within the list:

    if (CartProducts.Contains(p))
    

    But it ignores similar cartproducts and i don't seem to know what it checks on - the ID? or it all?

    Thanks in advance! :)

  • Martin Milan
    Martin Milan about 14 years
    Why override Object.Equals, which could have consequences elsewhere in the code? To me, it makes more sense to amend the search code accordingly, and not the underlying class of object being searched upon...
  • Jan Johansen
    Jan Johansen about 14 years
    Do you hvave some examples of this, .Find() or overriding the Object.Equals/GetHashCode?
  • Vilius Surblys
    Vilius Surblys about 14 years
    @Martin IT would be very broken if you wanted the comparison of two CartProduct objects to behave differently in different places.
  • Richard
    Richard about 14 years
    @Martin: Yes, it will be used whenever something tries to compare instances of your type. (If you want just a local effect use List<T>.Exists() passing in a method that does the comparison.)
  • Martin Milan
    Martin Milan about 14 years
    @Rowland - But I'm not saying he would have to change how a comparison works. If he wants a specific object, use Contains(). If he wants any object matching a specified criteria, use Find() with a suitable predicate (lamda expression)... I'm actually arguing that you don't touch the comparison code AT ALL - you just call the right method on the list for the task you're trying to accomplish...
  • Martin Milan
    Martin Milan about 14 years
    @Richard - Exists() just tells you that there is a suitable object there. If you want to return that object, you'll need Find() - with a suitable predicate as you have suggested.
  • Vilius Surblys
    Vilius Surblys about 14 years
    @Martin Appears I misinterpreted your comment to be something along the lines of "override Contains()". Agree that Find() could solve the issue, although I would suggest having a suitable equals method may be more useful in loads of other cases, as the OP didn't spot that the references for two instances of the same entity were different.
  • Mel Gerats
    Mel Gerats about 14 years
    how can Linq ever be overkill?
  • Richard
    Richard about 14 years
    @Martin: List.Contains determines existence using an object, List.Exists determines the same thing with a predicate.
  • Martin Milan
    Martin Milan about 14 years
    @Rowland It's horses for courses - but I would be reluctant to make such a fundamental change to a class of objects just to enable searching like this. You're right, it's one way of doing it - just not the way I would have gone myself...
  • Martin Milan
    Martin Milan about 14 years
    @Richard - True - but I think the original poster wants to actually retrieve the object, not merely test if it exists...
  • Martin Milan
    Martin Milan about 14 years
    @Richard - Actually - I see where you're coming from now. Either one of us could be right lol...
  • Martin Milan
    Martin Milan about 14 years
    @MEL - Why get mixed up in a query and type inference for something this simple? That said though, it might be more readable to someone not familiar with lamdas...
  • Vilius Surblys
    Vilius Surblys about 14 years
    +1 Good clear example, that shows the option that wouldn't be affected by changes elsewhere (i.e. if the Equals() method got changed for whatever reason)
  • zionpi
    zionpi almost 5 years
    but where is GetHashCode()?
  • user890332
    user890332 over 4 years
    You don't need to implement GetHashCode(). It works without it.