c# List.Contains() Method Returns False

后端 未结 9 1861
梦毁少年i
梦毁少年i 2021-01-28 06:04

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

相关标签:
9条回答
  • 2021-01-28 06:39

    You need to implement the IEqualityComparer

    More information on how to do it can be found here; http://msdn.microsoft.com/en-us/library/bb339118.aspx

    // Custom comparer for the class 
     class CarComparer : IEqualityComparer<Car>
    {
    // Products are equal if their names and product numbers are equal. 
    public bool Equals(Car x, Car y)
    {
    
        //Check whether the compared objects reference the same data. 
        if (Object.ReferenceEquals(x, y)) return true;
    
        //Check whether any of the compared objects is null. 
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;
    
        //Check whether the properties are equal. 
        return x.CarID == y.CarID && x.CarName == y.CarName;
    }
    
    // If Equals() returns true for a pair of objects  
    // then GetHashCode() must return the same value for these objects. 
    
    public int GetHashCode(Car car)
    {
        //Check whether the object is null 
        if (Object.ReferenceEquals(car, null)) return 0;
    
        //Get hash code for the Name field if it is not null. 
        string hashCarName = car.CarName == null ? 0 : car.CarName.GetHashCode();
    
        //Get hash code for the ID field. 
        int hashCarID = car.CarID.GetHashCode();
    
        //Calculate the hash code for the product. 
        return hashCarName ^ hashCarID;
    }
    

    Check for equality;

    CarComparer carComp = new CarComparer();
    bool blnIsEqual = CarList1.Contains(CarList2, carComp);
    
    0 讨论(0)
  • 2021-01-28 06:40

    You can add this code, by implementing IEquatable

    public class Car: IEquatable<Car>
    {
    
        ......
    
        public bool Equals( Car other )
        {
            return this.CarID  == other.CarID && this.CarName == other.CarName;
        }
    }
    

    Link : http://msdn.microsoft.com/fr-fr/library/vstudio/ms131187.aspx

    0 讨论(0)
  • 2021-01-28 06:41

    A collection can never "contain" a newly newed object which uses the default Object.Equals comparison. (The default comparison is ReferenceEquals, which simply compares instances. This will never be true comparing an existing Car with a new Car())

    To use Contains in this way, you will need to either:

    1. Override Car.Equals (and Car.GetHashCode) to specify what it means to be equivalent, or

    2. Implement an IEqualityComparer<Car> to compare the instances and specify that in your call to Contains.

    Note the side effect that in the first option, other uses of Car.Equals(Car) will also use this comparison.


    Otherwise, you can use Any and specify the comparison yourself (but IMHO this smells a little funny - a Car should know how to compare itself):

    if(myCars.Any(c=> c.CarID == Convert.ToInt64(strCar.Split(':')[1]) && c.CarName == strCar.Split(':')[2]))
    
    0 讨论(0)
  • 2021-01-28 06:43
    myCars.Contains(newCar)
    myCars.Where(c =>  c.CarID == newCar.CarID && c.CarName==newCar.CarName).Count() > 0
    
    0 讨论(0)
  • 2021-01-28 06:44

    Your car class needs to implement interface IEquatable and define an Equals method, otherwise the contains method is comparing the underlying references.

    0 讨论(0)
  • 2021-01-28 06:46

    Your Car class is a reference type. By default reference types are compared to each other by reference, meaning they are considered the same if they reference the same instance in memory. In your case you want them to be considered equal if they contain the same values.

    To change the equality behavior, you need to override Equals and GetHashCode.

    If two cars are equal only when ID and Name are equal, the following is one possible implementation of the equality members:

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

    This implementation has been created automatically by ReSharper.
    It takes into account null values and the possibility of sub-classes of Car. Additionally, it provides a useful implementation of GetHashCode.

    0 讨论(0)
提交回复
热议问题