Иногда, при работе с несколькими коллекциями или последовательностями элементов может потребоваться определить сам факт равенства или неравенства всех элементов в одной коллекции всем элементам во второй коллекции. В этом случае нам нет необходимости выполнять операции Except
или Intersect
над коллекциями. Для сравнения последовательностей элементов в LINQ используется метод SequenceEqual
.
Метод SequenceEqual
Этот метод возвращает True
, если две последовательности содержат одинаковое число элементов и каждый очередной элемент из первой коллекции совпадает с каждым очередным элементом во второй коллекции.
Продемонстрировать работу метода SequenceEqual
можно на следующем простом примере:
int[] ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; int[] ints2 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; int[] ints3 = new int[] { 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; string result = ints.SequenceEqual(ints2) ? "Коллекции 1 и 2 совпадают" : "Коллекции 1 и 2 НЕ совпадают"; Console.WriteLine(result); result = ints2.SequenceEqual(ints3) ? "Коллекции 2 и 3 совпадают" : "Коллекции 2 и 3 НЕ совпадают"; Console.WriteLine(result);
результат выполнения приложения в будет следующим:
Коллекции 2 и 3 НЕ совпадают
Несмотря на то, что массив ints3
содержит те же числа, то и массив ints2
, метод SequenceEqual
вернет false, так как сравнение элементов происходит поочередно — первый элемент первой последовательности сравнивается с первым элементом второй последовательности, второй элемент первой последовательности — со вторым элементом второй последовательности и так далее.
Сравнение последовательностей сложных объектов
Рассмотрим следующий пример:
Person p1 = new Person() { Name = "Вася", Age = 15 }; Person p2 = new Person() { Name = "Петя", Age = 15 }; Person[] people_1 = new Person[] {p1, p2}; Person[] people_2 = new Person[] {p1, p2}; if (people_1.SequenceEqual(people_2)) Console.WriteLine("Коллекции совпадают"); else Console.WriteLine("Коллекции не совпадают");
Здесь обе коллекции содержат по два одинаковых элемента, поэтому результат будет ожидаемым:
Изменим пример следующим образом:
Person[] people_1 = new Person[] { new Person() { Name = "Вася", Age = 15 }, new Person() { Name = "Петя", Age = 15 } }; Person[] people_2 = new Person[] { new Person() { Name = "Вася", Age = 15 }, new Person() { Name = "Петя", Age = 15 } }; if (people_1.SequenceEqual(people_2)) Console.WriteLine("Коллекции совпадают"); else Console.WriteLine("Коллекции не совпадают");
несмотря на то, что, на первый взгляд, элементы последовательностей остались те же, SequenceEqual
вернет false
, так как при сравнении элементов используется метод Equals()
, который проверяет два объекта на равенство, используя для этого ссылки на объект. Поэтому, если мы хотим сравнивать объекты по значениям их свойств, то должны переопределить метод Equals()
(и, желательно, GetHashCode
). Пример переопределения метода Equals() можно увидеть здесь.
Итого
Метод SequenceEqual
удобно использовать в том случае, если нам необходимо установить факт полного соответствия всех элементов одной последовательности всем элементам другой последовательности. Сравнение происходит поэлементно, а при сравнении сложных объектов используется метод object.Equals
, который необходимо переопределить, если необходимо сравнивать объекты по их свойствам.