Содержание
При работе с различными коллекциями и списками элементов, часто бывает необходимо проверить соответствуют ли элементы этого набора данных определенным условиям. В LINQ для проверки элементов последовательностей применяются методы All
, Any
и Contains
.
Методы All и Any
Метод All
проверяет соответствуют ли все элементы коллекции заданному условию и возвращает true
/false
в зависимости от результата проверки. Например
int[] numbers = { 1, 3, 6, 7, 8, 11, 12 }; if (numbers.All(x => x < 20)) Console.WriteLine("Все элементы массива меньше 20"); else Console.WriteLine("В массиве есть элементы больше или равный 20");
Результат
All
вернет true
, если коллекция пуста.В свою очередь, метод Any
проверяет соответствует ли хотя бы один элемент заданному условию:
if (numbers.Any(x => x % 2 == 0)) Console.WriteLine("В массиве есть хотя бы одно четное число"); else Console.WriteLine("В массиве нет четных чисел");
Any
вернет false
Метод Contains
Метод Contains
проверяет содержится ли заданный объект в коллекции. Например,
int[] numbers = { 2, 3, 4, 5 }; if (numbers.Contains(3)) Console.WriteLine("В массиве есть число 3");
Что касается проверки чисел, строк и т.д. с использованием Contains
, то здесь все довольно прозрачно. Иначе дело обстоит с классами, например, воспользуемся нашим списком измерений:
class Program { static void Main(string[] args) { List<DataObject> objects = new List<DataObject>() { new DataObject {Name = "Утро", Value = 12.5 }, new DataObject {Name = "День", Value = 12.1 }, new DataObject {Name = "Вечер", Value = 80.5 }, new DataObject {Name = "Ночь", Value = 11.3 }, new DataObject {Name = "Утро", Value = 10.7 }, new DataObject {Name = "День", Value = 12.1 }, new DataObject {Name = "Вечер", Value = 80.5 }, new DataObject {Name = "Вечер", Value = 11.3 } }; DataObject test = new DataObject { Name = "Вечер", Value = 11.3 }; if (objects.Contains(test)) Console.WriteLine("В списке есть элемент"); else Console.WriteLine("В списке нет элемента"); } }
Результатом выполнения программы будет строка:
Дело в том, что классы — это ссылочный тип данных. То есть, в нашем случае, переменная test
содержит не сами данные по измерению, а ссылку. И именно ссылки сравнивались в приведенном выше примере, т.е. ссылка на объект test
и ссылка на последний объект в списке — это разные ссылки на участки памяти где хранятся данные по объекту.
Чтобы Contains
заработал как нам необходимо, нам требуется переопределить метод Equals
базового типа object
, например, следующим образом:
public class DataObject { public string Name { get; set; } public double Value { get; set; } public override bool Equals(object obj) { return (obj == null) || (obj.GetType() != typeof(DataObject)) ? false : (Name == ((DataObject)obj).Name) && (Value == ((DataObject)obj).Value); } }
Теперь проверка пройдет успешно:
Итого
Сегодня мы разобрались с тем, как проверять элементы последовательностей на соответствие каким-либо критериям с использованием методов All
, Any
и Contains
. Для того, чтобы метод Contains мог проверять соответствие объектов по значению их свойств, необходимо переопределить у класс метод Equals
.