Я плохо знаком с лямбда-выражениями и смотрящий на рычаги синтаксис для устанавливания значения одного свойства в наборе на основе другого значения в наборе
Обычно я сделал бы цикл:
class Item
{
public string Name { get; set; }
public string Value { get; set; }
}
void Run()
{
Item item1 = new Item { Name = "name1" };
Item item2 = new Item { Name = "name2" };
Item item3 = new Item { Name = "name3" };
Collection<Item> items = new Collection<Item>() { item1, item2, item3 };
// This is what I want to simplify.
for (int i = 0; i < items.Count; i++)
{
if (items[i].Name == "name2")
{
// Set the value.
items[i].Value = "value2";
}
}
}
LINQ обычно более полезен для выбора данных, чем для изменения данных. Однако вы можете написать что-то вроде этого:
foreach(var item in items.Where(it => it.Name == "name2"))
item.Value = "value2";
Сначала выбираются элементы, которые необходимо изменить, а затем изменяются все они с помощью стандартного императивного цикла. Вы можете заменить цикл foreach
на метод ForAll
, доступный для списков, но я не думаю, что это дает вам какое-либо преимущество:
items.Where(it => it.Name == "name2").ToList()
.ForEach(it => it.Value = "value2");
Обратите внимание, что вам нужно добавить ToList
посередине, поскольку ForEach
- это функция .NET 2.0, доступная только для типа List
, а не для всех IEnumerable
типы (как и другие методы LINQ). Если вам нравится этот подход, вы можете реализовать ForEach
для IEnuerable
:
public static void ForEach<T>(this IEnumerable<T> en, Action<T> f) {
foreach(var a in en) f(a);
}
// Then you can omit the `ToList` conversion in the middle
items.Where(it => it.Name == "name2")
.ForEach(it => it.Value = "value2");
В любом случае, я бы предпочел цикл foreach
, потому что это также делает ясно, что вы делаете некоторую мутацию - и полезно легко увидеть этот факт в коде.