-
Notifications
You must be signed in to change notification settings - Fork 758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is the ordering in AssertEqualityComparer correct? #2612
Comments
Why IEnumerable? This lead to strange effects if you forget that your complex object implements IEnumerable. See #2485. |
To support equality for collections. |
The work to prevent double enumeration, which resulted in an overhaul of some of the assertion logic (especially as it relates to enumerables), means that 4-5-6 are now completely gone. That just leaves ordering, and I've decided to go with:
|
When looking at AssertEqualityComparer.Equals, clearly the ordering of the checks is important in terms of setting predictable priority.
As of the writing of this issue, the current priority list (from highest to lowest is):
IEquatable<T>
IComparable<T>
IComparable
IDictionary
ISet<T>
IEnumerable
IStructuralEquatable
IEquatable<T2>
whereT2
== the concrete type of second parametery
IComparable<T2>
whereT2
== the concrete type of second parametery
object.Equals()
You can group these into roughly 3 camps right now:
I see there are (at least) three potential issues right now:
Checking whether things are containers and should be treated like containers should be done fairly late in the list. The grouping of 7-9 is really much more similar to the grouping of 1-3, and should probably be moved up there. It's also worth considering what the interleaving of that should be; for example, should the order be more like 1/8/2/9/3 or 1/2/3/8/9? And where does 7 fit into the list?
The logic for 8/9 isn't exactly correct. It currently assumes that the second parameter (
y
) will potentially be the derived-from-T type, but there's no guarantee of that. The type T could be chosen as the base type based on either ofx
ory
being the more derived type. That should probably be fixed.Step 10 is that we fall back to
object.Equals()
(which itself will call overridden Equals methods on the first parameter when both are non-null). Should we try to determine if the user has implemented a custom Equals method, and move that logic higher up the list (in particular, before the collections)? This was inspired by a user tripping over their custom implementation ofEquals
being ignored on their type, because it also wasIEnumerable
.Also, I haven't verified this, but I'm guessing there are few (or maybe no) explicit ordering tests that validate the order that things happen in.
Lastly, this should be probably also become a documentation issue so that we have a page on xunit.net that describes the default ordering behavior of checks in v2 (and the differences for v3, if we decide to make any changes).
The text was updated successfully, but these errors were encountered: