3

我正在尝试制作一种可以比较任何两个列表是否相等的方法。我试图以一种验证一个列表的每个元素与另一个列表的每个元素具有相同值的方式比较它们。我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)); 
    }
}

这是我用来测试此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();
        }
    }

车类:

   class Car
    {
        public String make { get; set; }
        public String model { get; set; }
    }
4

3 回答 3

5

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

  • 覆盖Equals和类GetHashCode_Car

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

  • 仅使用值类型,因为它们的默认版本Equals将按照您的预期运行。请注意,这些值类型的所有字段和属性都必须符合此处给出的第一个或第三个选项(即,要么具有Equals并被GetHashCode覆盖,要么也是一个值类型)。一般来说,这并不是真正推荐的解决方案,我只是将其作为理论上的可能性提及。在您的情况下,它会有所帮助 - 尝试更改class Carstruct Car.

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

于 2013-11-09T21:39:50.777 回答
2

也许我遗漏了一些东西,但为什么不使用 SequenceEqual?

http://msdn.microsoft.com/en-us/library/bb348567(v=vs.110).aspx

Bool b = l1.SequenceEqual(l2);

请注意,序列中的对象仍然必须正确实现 Equals 和 GetHashCode。

于 2013-11-09T21:42:22.657 回答
1

也为您的汽车提供覆盖:

class Car
{
    public String make { get; set; }
    public String model { get; set; }
    public override bool Equals(object obj)
    {
        var other = obj as Car;
        return (other != null) 
                && (this.make == other.make) 
                && (this.model == other.model); 
    }
    public override int GetHashCode()
    {
        return make.GetHashCode() ^ model.GetHashCode();
    }
}
于 2013-11-09T22:06:25.857 回答