如果要比较各个元素,Equals如何隐式比较列表?

时间:2017-06-18 15:20:47

标签: c#

我有一个包含3个属性的Vendor对象:VendorId,CompanyName和Email:

我发现我可以覆盖Equals方法以比较两个供应商:

public override bool Equals(object obj)
        {
            if (obj == null || this.GetType() != obj.GetType())
                return false;
            Vendor v = (Vendor)obj;
            if (v != null
                && v.CompanyName == this.CompanyName
                && v.Email == this.Email
                && v.VendorId == this.VendorId)
                return true;
            return base.Equals(obj);
        }

...否则C#无法做,因为它不知道两个供应商对象何时相等,除非我特意指示它将两个供应商的每个对象属性相互比较。

现在,在我的单元测试中,我发现我实际上不仅可以比较供应商,还可以比较供应商列表:

CollectionAssert.AreEqual(listOfVendors1, listOfVendors2);

我获得了如下列表:

var listOfVendors1 = new List<Vendor>() {
new Vendor() { VendorId = 1, CompanyName="comp1", Email="e@yahoo.com" },
new Vendor() { VendorId = 2, CompanyName="comp2", Email="f@yahoo.com" }
};

和第二个清单:

var listOfVendors2 = new List<Vendor>() {
new Vendor() { VendorId = 1, CompanyName="comp1", Email="e@yahoo.com" },
new Vendor() { VendorId = 2, CompanyName="comp2", Email="f@yahoo.com" }
};

我注意到当CollectionAssert.AreEqual(listOfVendors1,listOfVendors2);处理后,我的自定义Equals方法被调用,首先是listOfVendors1.First()和listOfVendors2.First(),如果两个供应商的属性相等,则再次调用Equals方法,比较两个中的每个元素。名单。

我想了解使这成为可能的机制,因为我没有专门通过两个列表的元素进行迭代。如何,迭代何时完成?我很困惑。

如果要比较单个元素,Equals如何比较隐式(?)列表?例如Vendor1.Equals(供应商2)

2 个答案:

答案 0 :(得分:4)

  

我想了解使这成为可能的机制,因为我不会专门通过两个列表的元素进行迭代。如何,迭代何时完成?我很困惑。

SequenceEqual方法与CollectionAssert.AreEqual方法完全相同。如果你想知道它是如何工作的,你可以在这里阅读源代码:

https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs

总结:它在同一个循环中迭代两个序列,并在每对元素上调用Equal。

如果你需要做一些事情而不是比较两个序列中绘制的元素对的相等性,你可以使用Zip序列运算符;如果你看一下它的实现,你会发现它与SequenceEqual类似,不足为奇。

答案 1 :(得分:0)

CollectionAssert.AreEqual(listOfVendors1, listOfVendors2);

将在内部迭代您的列表并检查所有项目是否与值和订单匹配。要确定对象的相等性,它将使用您的自定义Equals方法(如果可用),否则它将使用默认比较。