Reputation: 413
I have a Vendor object with 3 properties: VendorId, CompanyName and Email:
I have found that I can override the Equals method in order to compare two Vendors:
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);
}
...which otherwise C# can't do as it doesn't know when two vendor objects are equal, unless I instruct it specifically to compare every object property of two vendors to each other.
Now, in my unit test I found that I can actually compare not only vendors, but list of vendors:
CollectionAssert.AreEqual(listOfVendors1, listOfVendors2);
and I obtained the lists as follows:
var listOfVendors1 = new List<Vendor>() {
new Vendor() { VendorId = 1, CompanyName="comp1", Email="[email protected]" },
new Vendor() { VendorId = 2, CompanyName="comp2", Email="[email protected]" }
};
and for the second list:
var listOfVendors2 = new List<Vendor>() {
new Vendor() { VendorId = 1, CompanyName="comp1", Email="[email protected]" },
new Vendor() { VendorId = 2, CompanyName="comp2", Email="[email protected]" }
};
I noticed that when CollectionAssert.AreEqual(listOfVendors1, listOfVendors2); is processed, my custom Equals method is called, first for listOfVendors1.First() and listOfVendors2.First() and if the properties of the two vendors are equal, the Equals method is called again, comparing the second elements from each of the two lists.
I would like to understand the mechanism that makes this possible, since I don't iterate specifically through the elements of the two lists. How, when is the iteration done? I'm confused.
How does Equals compare implicitly(?) lists, if it is intended to compare individual elements? e.g. Vendor1.Equals(Vendor2)
Upvotes: 0
Views: 310
Reputation: 660004
I would like to understand the mechanism that makes this possible, since I don't iterate specifically through the elements of the two list. How, when is the iteration done? I'm confused.
The SequenceEqual
method does pretty much the same thing as your CollectionAssert.AreEqual
method. If you want to know how it works, you can read the source code here:
https://github.com/Microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs
In summary: it iterates both sequences in the same loop and calls Equal on each pair of elements.
If you need to do something other than compare equality to pairs of elements drawn from two sequences, you can use the Zip
sequence operator; if you look at its implementation you'll find it is unsurprisingly similar to SequenceEqual
.
Upvotes: 4
Reputation: 814
CollectionAssert.AreEqual(listOfVendors1, listOfVendors2);
Will internally iterate over your lists and check if all the items match value and order. To determine the equality of the objects it will use your custom Equals
methods if available, else it would use the default comparison.
Upvotes: 0