c#List <T> .Contains()方法返回False

s15*_*99d 0 c# asp.net

在下面的代码块中,我希望dictCars包含:{Chevy:Camaro,Dodge:Charger}

但是,dictCars回来了.因为每次调用此行都返回false:

if(myCars.Contains(new Car(Convert.ToInt64(strCar.Split(':')[1]),strCar.Split(':')[2])))
Run Code Online (Sandbox Code Playgroud)

代码块:

public class Car
{
    public long CarID { get; set; }

    public string CarName { get; set; }

    public Car(long CarID, string CarName)
    {
        this.CarID = CarID;
        this.CarName = CarName;
    }
}

List<Car> myCars = new List<Car>();
myCars.Add(new Car(0,"Pinto"));
myCars.Add(new Car(2,"Camaro"));
myCars.Add(new Car(3,"Charger"));

Dictionary<string, string> dictCars = new Dictionary<string, string>();
string strCars = "Ford:1:Mustang,Chevy:2:Camaro,Dodge:3:Charger";
String[] arrCars = strCars.Split(',');
foreach (string strCar in arrCars)
{
    if(myCars.Contains(new Car(Convert.ToInt64(strCar.Split(':')[1]),strCar.Split(':')[2])))
    {
        if (!dictCars.ContainsKey(strCar.Split(':')[0]))
        {
            dictCars.Add(strCar.Split(':')[0], strCar.Split(':')[2]);
        }
    }
}

return dictCars;
Run Code Online (Sandbox Code Playgroud)

问题:我的List.Contains实现有什么问题?

提前致谢!

D S*_*ley 7

你需要告诉包含什么使两个Cars相等.默认情况下,如果它们是同一个实例,它将使用ReferenceEquals只调用两个相等的对象.

在您的类中覆盖Equals和定义一个类并将其传递给.GetHashCodeCarIEqualityComparer<Car>Contains

如果两个Car具有相同的CarID是"相等",则实现非常简单:

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();
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*rth 5

您的Car类是引用类型.默认情况下,引用类型相互比较的基准,这意味着它们被认为是相同的,如果它们引用相同的实例在内存中.在您的情况下,如果它们包含相同的值,您希望它们被视为相等.

要更改相等行为,您需要覆盖EqualsGetHashCode.

如果两辆车在相同IDName相等的情况下相等,则以下是平等成员的一种可能实现:

protected bool Equals(Car other)
{
    return CarID == other.CarID && string.Equals(CarName, other.CarName);
}

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj))
        return false;
    if (ReferenceEquals(this, obj))
        return true;
    var other = obj as Car;
    return other != null && Equals(other);
}

public override int GetHashCode()
{
    unchecked
    {
        return (CarID.GetHashCode() * 397) ^ 
                (CarName != null ? CarName.GetHashCode() : 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

此实现由ReSharper自动创建.
它考虑了null价值观和子类的可能性Car.此外,它提供了有用的实现GetHashCode.