Есть ли лучший способ выполнить эти назначения с помощью LINQ?
IEnumerable<SideBarUnit> sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID);
foreach (SideBarUnit su in sulist1) su.color = "Red";
Есть ли лучший способ выполнить эти назначения с помощью LINQ?
IEnumerable<SideBarUnit> sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID);
foreach (SideBarUnit su in sulist1) su.color = "Red";
Вы можете сделать так, как указывают другие ответы, но затем вы больше не используете LINQ.
Эрик Липперт написал отличное сообщение в блоге об этом самом предмете, которое я настоятельно рекомендую вам прочитать. Вот выдержка:
Я философски возражаю против предоставления такого метода по двум причинам.
Первая причина заключается в том, что это нарушает принципы функционального программирования, на которых основаны все другие операторы последовательности. Очевидно, что единственная цель вызова этого метода - вызвать побочные эффекты.
Цель выражения - вычислить значение, а не вызывать побочный эффект.
...
Вторая причина заключается в том, что это добавляет ноль новой репрезентативной мощности для языка. Это позволит вам переписать этот совершенно чистый код:
foreach(Foo foo in foos){ statement involving foo; }
в этот код:
foos.ForEach((Foo foo)=>{ statement involving foo; });
который использует почти точно такие же символы в несколько ином порядке. И все же вторая версия сложнее понять, сложнее отладить и вводит семантику закрытия, тем самым потенциально изменяя сроки жизни объектов тонким образом.
Самый простой способ - определить метод расширения foreach
, который позволяет добавить его в конец запроса такого типа. Например
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) {
foreach (var cur in enumerable) {
action(cur);
}
}
...
использование:
newlist
.Where(c => c.StatusID == EmergencyCV.ID)
.ForEach(cur => cur.color = "Red");
Используя метод List.ForEach():
IEnumerable<SideBarUnit> sulist1 =
newlist.Where(c => c.StatusID == EmergencyCV.ID)
.ToList()
.ForEach(item => item.color = "Red");
PS: Я знаю об Eric Lippert статье aboout ForEach() vs foreach
, но в любом случае это полезно, и я предпочитаю его, а не for/foreach
РЕДАКТИРОВАТЬ: относительно вопроса в комментариях о достижениях производительности
Enumerable.ToList()
реализован как
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
return new List<TSource>(source);
}
так что поражение производительности - это время для создания нового экземпляра List<>()
.
MSDN говорит следующее для Список < > (IEnumerable < > ) ctor:
Инициализирует новый экземпляр класса List, который содержит элементы скопирован из указанной коллекции и имеет достаточную емкость для размещения количества скопированных элементов.
Итак, будет операция копирования всего списка
Linq - это выбор, а не обновление. Но вы можете использовать ToList и List ForEach для обновления элементов:
newlist.Where(c => c.StatusID == EmergencyCV.ID).
ToList().
ForEach(su => su.color = "Red");
Я не уверен, что читаемость лучше, хотя...
Цель LINQs заключается в основном в запросе/проекте/преобразовании данных.
Возможно, вы захотите использовать метод расширения ForEach. Но см. эту дискуссию для более подробной информации.
Вы можете использовать анонимный метод в инструкции Select:
var sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID)
.Select(c => {
c.color = "Red";
return c;
});