In the code block below I would expect dictCars to contain: { Chevy:Camaro, Dodge:Charger }
But, dictCars comes back empty. Because this line returns false each time it
You need to implement Equals. Most probably as:
public override bool Equals(object obj)
{
Car car = obj as Car;
if(car == null) return false;
return car.CarID == this.CarID && car.CarName == this.CarName;
}
You need to tell Contains what makes two Car
s equal. By default it will use ReferenceEquals
which will only call two objects equal if they are the same instance.
Either override Equals
and GetHashCode
in your Car
class or define an IEqualityComparer<Car>
class and pass that to Contains
.
If two Car
s that have the same CarID
are "equal" then the implementation is pretty straightforward:
public override bool Equals(object o)
{
if(o.GetType() != typeof(Car))
return false;
return (this.CarID == ((Car)o).CarID);
}
public override int GetHashCode()
{
return CarID.GetHashCode();
}
You are assuming that two Car instances that have the same CarID and CarName are equal.
This is incorrect. By default, each new Car(...)
is different from each other car, since they are references to different objects.
There are a few ways to "fix" that:
Use a struct instead of a class
for your Car.
Structs inherit ValueType
's default implementation of Equals
, which compares all fields and properties to determine equality.
Note that in this case, it is recommended that you make your Car
struct immutable to avoid common problems with mutable structs.
Override Equals and GetHashCode.
That way, List.Contains
will know that you intend Cars with the same ID and Name to be equal.
Use another method instead of List.Contains
.
For example, Enumerable.Any allows you to specify a predicate that can be matched:
bool exists = myCars.Any(car => car.ID == Convert.ToInt64(strCar.Split(':')[1])
&& car.Name = strCar.Split(':')[2]);