试图实现一个可以比较任何两个列表的方法,但它总是返回false

Tyl*_*aff 3 c# comparison ienumerable list

我正在尝试创建一个方法,可以比较任何两个列表的相等性.我试图以一种验证一个列表的每个元素与另一个列表的每个元素具有相同值的方式来比较它们.Equals下面我的方法总是返回false,有人能看出为什么会这样吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class IEnumerableComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        for(int i = 0; i<x.Count();i++){
          if(!Object.Equals(x.ElementAt(i), y.ElementAt(i))){
             return false;
          }
        }
        return true;
    }

    public int GetHashCode(IEnumerable<T> obj)
    {
        if (obj == null)
            return 0;

        return unchecked(obj
            .Select(e => e.GetHashCode())
            .Aggregate(0, (a, b) => a + b)); 
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我用于测试此Equals方法的数据:

 static void Main(string[] args)
        {
            Car car1 = new Car();
            car1.make = "Toyota";
            car1.model = "xB";

            Car car2 = new Car();
            car2.make = "Toyota";
            car2.model = "xB";

            List<Car> l1 = new List<Car>();
            List<Car> l2 = new List<Car>();
            l1.Add(car1);
            l2.Add(car2);

           IEnumerableComparer<Car> seq = new IEnumerableComparer<Car>();

           bool b = seq.Equals(l1, l2);

           Console.Write(b); //always says false
           Console.Read();
        }
    }
Run Code Online (Sandbox Code Playgroud)

车类:

   class Car
    {
        public String make { get; set; }
        public String model { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

Bar*_*zKP 5

Equals比较引用的默认版本(对于引用类型).您的问题有三种可能的解决方案:

  • 覆盖EqualsGetHashCodeCar

  • 添加另一个版本的IEnumerableComparer<T>构造函数接受IEqualityComparer<T>,它将用于比较各个实例并为每个用例提供其实现

  • 仅使用值类型,因为它们的默认版本Equals将按预期运行.请注意,这些值类型的所有字段和属性都必须符合此处给出的第1个或第3个选项(即具有EqualsGetHashCode重写或者也是值类型).一般来说,这不是一个真正推荐的解决方案,我只是提到它作为理论上的可能性.在你的情况下,它会有所帮助 - 尝试class Car改为struct Car.

另外,正如wageoghe的答案正确指出的那样,您可以使用该SequenceEqual方法而不是编写自己的实现,但仍然需要遵守上面给出的解决方案之一(SequenceEqual对于第二个选项使用此重载).