I come across a bug where given two list of objects, if they are not equivalent then something will update. The bug was that even though the two lists are not equivalent, nothing was updated in the database. When looking into the code, it was something like this. The SomeObjectComparer is used to determine if two objects are equal since SomeObject is a complex object.
public void UpdateIfHasChanges(List<SomeObject> current, List<SomeObject> newChanges)
{
if (current.Except(newChanges, new SomeObjectComparer()).Any() ||
newChanges.Except(current, new SomeObjectComparer()).Any())
{
// Update something here
}
}
Or to make the example simpler, I’ll use a list of string here
public void UpdateIfNotEquivalent(List<string> current, List<string> newChanges)
{
if (current.Except(newChanges).Any() ||
newChanges.Except(current).Any())
{
// Update something here
}
}
That code above will probably work if the lists can only have unique values. Something like days of the week the business is open. If there are two Mondays in newChanges and only one Monday in current, they are still equivalent and you might treat it as no differences between them (this obviously depends on each domain requirement).
var current = new[] { "Monday", "Tuesday" };
var newChanges = new[] { "Monday", "Monday", "Tuesday" };
However, in cases where the requirement treats the above as not equivalent then this way of checking if the lists are different would give you the wrong result. Both current.Except(newChanges) and newChanges.Except(current) will have no values.
The developer we had working on this bug initially suggested adding length check before doing the Excepts.
if (current.Count != newChanges.Count ||
current.Except(newChanges).Any() ||
newChanges.Except(current).Any())
{
// Update something here
}
This fix only works if the lengths of the lists are different. It would still fail with this example
var current = new[] { "Monday", "Tuesday", "Tuesday" };
var newChanges = new[] { "Monday", "Monday", "Tuesday" };
Conclusion
Checking if two lists are equivalent can be complex or simple depending on the business requirements (whether duplicates are allowed, or if order of items matter, etc.). It can be quite complex if you need to deal with complex objects with lots of nested complex properties.