Назначение значений внутри LINQ Select?
У меня есть следующий запрос:
drivers.Select(d => { d.id = 0; d.updated = DateTime.Now; return d; }).ToList();
драйверы - это список, в который входят разные идентификаторы и обновленные значения, поэтому я изменяю значения в Select, но это правильный способ сделать это. Я уже знаю, что я не переназначаю драйверы драйверам, потому что Resharper жалуется на это, поэтому я думаю, было бы лучше, если бы это было:
drivers = drivers.Select(d => { d.id = 0; d.updated = DateTime.Now; return d; }).ToList();
но это все еще так, как кто-то должен назначать новые значения для каждого элемента в списке драйверов?
Ответы
Ответ 1
Хотя это выглядит невинно, особенно в сочетании с вызовом ToList
который немедленно ToList
код, я определенно избегаю модификации чего-либо как части запроса: трюк настолько необычен, что он будет затягивать читателей вашей программы, даже опытных, особенно если они никогда не видели этого раньше.
Нет ничего плохого в петлях foreach
- факт, что вы можете сделать это с LINQ, не означает, что вы должны это делать.
Ответ 2
НИКОГДА НЕ ДЕЛАЙТЕ ЭТО. Запрос должен быть запросом; это должно быть неразрушающим образом задавать вопросы источника данных. Если вы хотите вызвать побочный эффект, используйте цикл foreach
; что это для. Используйте правильный инструмент для работы.
Ответ 3
Хорошо, я сам отвечу.
Xaisoft, запросы Linq
, будь то выражение lambda или выражение запроса, не должны использоваться для изменения списка. Следовательно, ваш Select
drivers = drivers.Select(d => { d.id = 0; d.updated = DateTime.Now; return d; }).ToList();
плохой стиль. Это смущает/нечитабельно, а не стандартно, а также против философии Linq
. Еще один плохой стиль достижения конечного результата:
drivers.Any(d => { d.id = 0; d.updated = DateTime.Now; return false; });
Но это не ForEach
что ForEach
on List<T>
не подходит. Он находит использование в таких случаях, как ваш, но не смешивает мутацию с запросом Linq
, вот и все. Я предпочитаю писать что-то вроде:
drivers.ForEach(d => d.updated = DateTime.Now);
Его элегантный и понятный. Поскольку это не касается Linq
, это тоже не смущает. Мне не нравится этот синтаксис для нескольких операторов (как в вашем случае) внутри лямбда. Это немного менее читаемо и сложнее отлаживать, когда все становится сложным. В вашем случае я предпочитаю прямой цикл foreach
.
foreach (var d in drivers)
{
d.id = 0;
d.updated = DateTime.Now;
}
Лично мне нравится ForEach
на IEnumerable<T>
как завершающий вызов выражения Linq
(т. Linq
Если назначение не предназначено для запроса, а является исполнением).