Может ли ReSharper генерировать элементы равенства, которые правильно сравнивают элементы коллекции? - PullRequest
0 голосов
/ 02 февраля 2019

Скажем, у вас есть класс с членами, которые являются коллекциями, например.

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

Когда я генерирую элементы равенства с ReSharper, коллекции не сравниваются корректно.Сгенерированный метод Equals () при сравнении коллекций использует public static bool Equals(object objA, object objB), определенный в Object:

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

Разве он не должен использовать Enumerable.SequenceEqual(), как Trees.SequenceEqual(other.Trees)?Нужно ли вручную изменять сгенерированный Equals () для использования Enumerable.SequenceEqual(), или есть какой-то лучший способ, не требующий изменения сгенерированного кода?

1 Ответ

0 голосов
/ 05 февраля 2019

ReSharper не пытается выполнить глубокую проверку коллекции на равенство, так как он не знает, как это сделать для каждого типа коллекции (и что именно означает «тип коллекции»?).Кроме того, большинство типов изменяемых коллекций представлены сложными объектами (например, хранящими в элементах сравнения равенства элементов), а не простыми «значениями» (в отличие от неизменяемых коллекций), которые можно легко проверить на равенство.

Всегда генерируетEnumerable.SequenceEquals() не является хорошей идеей в большинстве случаев, поскольку он работает на слишком абстрактных IEnumerable<T> интерфейсах - он даже не проверяет коллекции .Count, чтобы вернуть false рано.Кроме того, некоторые из набороподобных коллекций для двух равных наборов не гарантируют одинаковый порядок элементов при перечислении с использованием интерфейса IEnumerable<T>.

Некоторые неизменяемые коллекции имеют специальные API для сравнения на равенство (как ни странно, ImmtableListв отличие от ImmutableHashSet.SetEquals) такого API нет, но у ReSharper нет специальных знаний по таким API.Имея все это в виду, мы решили придерживаться генерации вызовов object.Equals(), предоставляя пользователю возможность уточнить намерения.Возможно, нам следует создать комментарий в сгенерированном коде, поясняющий это ...

В вашем конкретном случае я предлагаю сначала сравнить .Count из ImmutableList и использовать Enumerable.SequenceEquals() после.

...