试图实现一个可以比较任何两个列表的方法,但它总是返回false
我正在尝试创建一个方法,可以比较任何两个列表的相等性。 我试图以一种validation一个列表的每个元素与另一个列表的每个元素具有相同值的方式来比较它们。 下面的My Equals
方法总是返回false
,有人能看出为什么会这样吗?
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; public class IEnumerableComparer : IEqualityComparer<IEnumerable> { public bool Equals(IEnumerable x, IEnumerable 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 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 l1 = new List(); List l2 = new List(); l1.Add(car1); l2.Add(car2); IEnumerableComparer seq = new IEnumerableComparer(); 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; } }
Equals
的默认版本比较引用(对于引用类型)。 您的问题有三种可能的解决方案:
-
覆盖
Car
类的Equals
和GetHashCode
-
添加另一个版本的
IEnumerableComparer
构造函数,接受IEqualityComparer
,它将用于比较各个实例并为每个用例提供实现 -
仅使用值类型,因为它们的默认版本
Equals
将按预期运行。 请注意,这些值类型的所有字段和属性都必须符合此处给出的第1个或第3个选项(即,要么重写Equals
和GetHashCode
要么也是值类型)。 一般来说,这不是一个真正推荐的解决方案,我只是提到它作为理论上的可能性。 在你的情况下,它会有所帮助 – 尝试将class Car
更改为struct Car
。
另外,正如wageoghe的答案正确指出的那样,您可以使用SequenceEqual
方法而不是编写自己的实现,但仍需要遵守上面给出的解决方案之一(对于第二个选项使用此SequenceEqual
重载)。
也许我错过了什么,但为什么不使用SequenceEqual?
http://msdn.microsoft.com/en-us/library/bb348567(v=vs.110).aspx
Bool b = l1.SequenceEqual(l2);
请注意,序列中的对象仍然必须正确实现Equals和GetHashCode。
也为你的车提供覆盖:
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(); } }