Элегантный и практичный yield
Начинающие программисты при работе с коллекциями часто не придают значения оптимизации производительности (например, при работе с БД). Допустим, программист хочет реализовать функцию, возвращающую список сотрудников с оформленными ими заказами. В дальнейшем эту функцию будут использовать для отображения на внутреннем портале организации. Он делает это так:
public List<Person> GetPersonsWithOrders1() { var result = new List<Person>(); foreach (var person in GetPersons()) { person.Orders = GetOrdersForPerson(person); result.Add(person); } return result; }
Сначала он получает из БД список сотрудников (в котором может быть 300-500 человек), и по каждому сотруднику подтягивается информация об обработанных им заказах, число которых может достигать нескольких сотен или даже тысяч.
Команда, работающая над порталом организации, оформила список сотрудников с постраничной навигацией. Но время получения информации при этом не уменьшилось, поскольку информация по всем сотрудникам и всем заказам запрашивается каждый раз, даже если пользователь портала открывает только первую страницу со списком сотрудников, где отображается 10 человек.
Для решения данной проблемы достаточно немного доработать первую функцию:
public IEnumerable<Person> GetPersonsWithOrders2() { foreach (var person in GetPersons()) { person.Orders = GetOrdersForPerson(person); yield return person; } }
Здесь мы используем неоправданно забытое многими программистами ключевое слово yield.
Что это даёт?
Во-первых, код становится короче и удобнее для чтения.
Во-вторых, в случае следующего вызова метода
А как вы используете yield? Пишите в комментариях!