Содержание
При работе с различными коллекциями и списками элементов, часто бывает необходимо проверить соответствуют ли элементы этого набора данных определенным условиям. В 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.