'Can ReSharper generate equality members that correctly compare Collection members?

Say you have a class with members that are collections, such as.

public class Forest {
    public IImmutableList<Tree> Trees { get; }
    . . .
}

When I generate equality members with ReSharper, the collections do not compare correctly. The generated Equals() method, when comparing collections, uses public static bool Equals(object objA, object objB) defined in Object:

protected bool Equals(Forest other)
{
    return Equals(Trees, other.Trees);
}

Shouldn't it use Enumerable.SequenceEqual(), like Trees.SequenceEqual(other.Trees)? Do I need to manually change the generated Equals() to use Enumerable.SequenceEqual(), or is there some better way that doesn't require modifying generated code?



Solution 1:[1]

ReSharper does not try to perform deep equality collection check on collection, since it has no idea how to do it for each and every collection type (and what exactly a "collection type" means?). Also, most of the mutable collection types are represented with complex objects (storing element equality comparers inside, for example), not the simple "values" (unlike immutable collections) that can be checked for equality easily.

Always generating Enumerable.SequenceEquals() is not a good idea most of the time, since it's operates over too abstract IEnumerable<T> interfaces - it does not even check the collections .Count to return false early. Also, some of set-like collections for the two equal sets do not guarantee the same order of elements when enumerating using IEnumerable<T> interface.

Some immutable collections have special APIs for equality comparison (strangely enough, ImmtableList has no such API, unlike ImmutableHashSet.SetEquals), but ReSharper has no special knowledge for such APIs. With all that in mind, we decided to stick with object.Equals() invocation generation, leaving the user with the ability to clarify intentions. Maybe we should produce comments in generated code clarifying this...

In your particular case, I suggest to compare .Count of ImmutableList first and use Enumerable.SequenceEquals() afterwards.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pang