C# .NET - C# LIst Contains method - Asked By Alek Tolstoi on 23-Jul-09 11:53 AM

I am trying to implement the Contains method, but i am running into some issues. Can someone help?

For example:

Class Car has the following properties:

Name

Year

List<Car> myCars

myCars list has 10 cars

I want to see if a certain car is there, I don't want to use the loop for every car that i might have to search the list.

I was hoping to do something like this:

myCars.Contains("Honda")

is that possible?

Thanks

Al

Yes, you can do it. - Peter Bromberg replied to Alek Tolstoi on 23-Jul-09 01:09 PM

The Contains method is an instance method on the List type. However, you would only be able to use Contains("Honda") if you had a list of <String>. You will need to use a predicate filter if you want to search all your <Car> objects on one of their properties, which I assume here is something like "Name".

Predicate... - Alek Tolstoi replied to Peter Bromberg on 23-Jul-09 01:12 PM

I tried using the predicate, however, my .net 2.0 is not recognizing the keyword. I checked with MSDN and it says, that the generic Predicate is part of 2.0 and I know that I am building on .net 2.0. Any ideas?

Thanks
Al

Technically possible, but... - Adam Houldsworth replied to Alek Tolstoi on 23-Jul-09 01:59 PM

Hi,

You can change the behaviour of Contains by overriding the object's Equals method - however this change my affect other uses of .Equals as its a base object method.  You would also need to give the Contains method a new instance of your class, so you would need to wrap your 'Honda' in a new Car object anyway...

My advice would be to create your own class that derives from List<Car> (call it CarList or something) and add an overloaded method for Contains to take a string parameter - obviously your custom list will be a list of only Car objects as it would need to know what property to check against.

You could get really clever and implement a custom collection yourself similar to List<T> that can take an object value and a property name parameter and you use reflection to perform the Contains.

I tend to make custom lists anyway, one for self-documenting code, and two just in case I need to embed custom behaviour in future.  I either inherit from List<> or BindingList<> depending on if its data bound or not.

Adam

List uses IEquatable<(Of <(T>)>) interface - [)ia6l0 iii replied to Alek Tolstoi on 23-Jul-09 02:12 PM
to determine the equality of the instances of the specified type.

So Implement this interface for your 'CAR' class. Like,

public class Car : IEquatable<Car>
{
    public string Name;

    public Car(string name)
    {
        this.Name = name;
    }

    public bool Equals(Car other)
    {
        if (other == null) return false;
        return (this.Name.Equals(other.Name));
    }
}

You can read about IEquatable interface http://msdn.microsoft.com/en-us/library/ms131187.aspx.
Solution Merge - Adam Houldsworth replied to Alek Tolstoi on 23-Jul-09 02:18 PM

Furthering Diablo's solution (I wasn't aware of this interface, learn something new every day :), you can implement the IEquatable interface explicitly so that you can maintain the objects inherited behaviour via the Object.Equals method, but allow consumers of the interface to use the interface version.

You can implement an interface explicitly using the Visual Studio right-click option on the interface name, or manually:

bool IEquatable.Equals(Car myCar)

Adam

Little Trick - Adam Houldsworth replied to Adam Houldsworth on 23-Jul-09 02:22 PM

This is a standard trick for object designers 1 to avoid name clashes and 2 to reduce the public interface of classes.

I personally use it for cloneable objects:

public MyClass Clone() { }
object ICloneable.Clone()
{
    return this.Clone(); 
}

In my example, you can only call the ICloneable.Clone method if you cast your instance of MyClass to ICloneable first... otherwise access Clone on a MyClass type will take you to the public method.

Adam

 
how? - Alek Tolstoi replied to Adam Houldsworth on 23-Jul-09 03:40 PM
maybe i am not seeing the "How?" to implement, but I don't want to hard code "Honda" as my comparer, i want to be able to pass any name into my car list comparer and determine if the car is in the list return boolean back?



Thank you ALL!!!! - Alek Tolstoi replied to Alek Tolstoi on 23-Jul-09 03:56 PM
Thank you all for your help, but i found my solution to be:

        private static bool IsCarInListCheck(List<Car> list, string nameToCheck)
        {          
            return list.Exists((x => x.Name == nameToCheck));
        }


Regards,

Al
RE - Ravenet Rasaiyah replied to Alek Tolstoi on 23-Jul-09 11:11 PM
Hi

You can  use the linq in this way ,

mycar =myCars.find(delegate(Car linqcar)
{
return mycar.Name=linqcar.Name;
});
if (mycar==null)
{
// not found
}
else
{
// not exist
}


Thank you
http://www.codegain.com


Lamda solution - George Loveless replied to Alek Tolstoi on 06-Jan-10 12:32 PM
The following should work as well using lamdas.  I was having the same issue

if( myCars.any(x => x.toLower() == "honda")
{
        //  yup, there's a honda in your car list
}