Есть ли способ установить значения в LINQ?

Есть ли лучший способ выполнить эти назначения с помощью LINQ?

IEnumerable<SideBarUnit> sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID);
foreach (SideBarUnit su in sulist1) su.color = "Red";

Ответ 1

Нет.

Вы можете сделать так, как указывают другие ответы, но затем вы больше не используете LINQ.

Эрик Липперт написал отличное сообщение в блоге об этом самом предмете, которое я настоятельно рекомендую вам прочитать. Вот выдержка:

Я философски возражаю против предоставления такого метода по двум причинам.

Первая причина заключается в том, что это нарушает принципы функционального программирования, на которых основаны все другие операторы последовательности. Очевидно, что единственная цель вызова этого метода - вызвать побочные эффекты.

Цель выражения - вычислить значение, а не вызывать побочный эффект.

...

Вторая причина заключается в том, что это добавляет ноль новой репрезентативной мощности для языка. Это позволит вам переписать этот совершенно чистый код:

foreach(Foo foo in foos){ statement involving foo; }

в этот код:

foos.ForEach((Foo foo)=>{ statement involving foo; });

который использует почти точно такие же символы в несколько ином порядке. И все же вторая версия сложнее понять, сложнее отладить и вводит семантику закрытия, тем самым потенциально изменяя сроки жизни объектов тонким образом.

Ответ 2

Самый простой способ - определить метод расширения 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");

Ответ 3

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

Итак, будет операция копирования всего списка

Ответ 4

Linq - это выбор, а не обновление. Но вы можете использовать ToList и List ForEach для обновления элементов:

newlist.Where(c => c.StatusID == EmergencyCV.ID).
  ToList().
  ForEach(su => su.color = "Red");

Я не уверен, что читаемость лучше, хотя...

Ответ 5

Цель LINQs заключается в основном в запросе/проекте/преобразовании данных.

Возможно, вы захотите использовать метод расширения ForEach. Но см. эту дискуссию для более подробной информации.

Ответ 6

Вы можете использовать анонимный метод в инструкции Select:

var sulist1 = newlist.Where(c => c.StatusID == EmergencyCV.ID)
                     .Select(c => {
                                     c.color = "Red";
                                     return c;
                                  });