Стиль Linq "Для каждого"
Возможный дубликат:
Linq эквивалент foreach для IEnumerable
Есть ли какой-либо синтаксис стиля Linq для операций "Для каждого"?
Например, добавьте значения, основанные на одной коллекции, другой, уже существующей:
IEnumerable<int> someValues = new List<int>() { 1, 2, 3 };
IList<int> list = new List<int>();
someValues.ForEach(x => list.Add(x + 1));
Вместо
foreach(int value in someValues)
{
list.Add(value + 1);
}
Ответы
Ответ 1
Использование метода расширения ToList() - ваш лучший вариант:
someValues.ToList().ForEach(x => list.Add(x + 1));
В BCL нет метода расширения, который напрямую реализует ForEach.
Хотя в BCL нет метода расширения, который делает это, в пространстве имен System
есть еще опция... если вы добавите Reactive Extensions к вашему проекту:
using System.Reactive.Linq;
someValues.ToObservable().Subscribe(x => list.Add(x + 1));
Это имеет тот же конечный результат, что и предыдущее использование ToList
, но является (теоретически) более эффективным, поскольку оно передает значения непосредственно делегату.
Ответ 2
Array
и List<T>
классы уже имеют методы ForEach
, хотя это только конкретная реализация. (Обратите внимание, что первая static
, кстати).
Не уверен, что это действительно дает большое преимущество над оператором ForEach
, но вы можете написать метод расширения для выполнения задания для всех объектов IEnumerable<T>
.
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (var item in source)
action(item);
}
Это позволит точно указать код, который вы разместили в своем вопросе, для работы так, как вы хотите.
Ответ 3
Нет ничего встроенного, но вы можете легко создать свой собственный метод расширения для этого:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
if (source == null) throw new ArgumentNullException("source");
if (action == null) throw new ArgumentNullException("action");
foreach (T item in source)
{
action(item);
}
}
Ответ 4
Официальная строка MS "потому что это не функциональная операция" (т.е. это операция с состоянием).
Не могли бы вы сделать что-то вроде:
list.Select( x => x+1 )
или если вам это действительно нужно в списке:
var someValues = new List<int>( list.Select( x => x+1 ) );
Ответ 5
В стандартном Linq нет ничего подобного, но есть оператор ForEach в MoreLinq.
Ответ 6
Нет расширения Linq ForEach. Однако класс List
имеет на нем метод ForEach, если вы хотите напрямую использовать List
.
Для того, что стоит, стандартный синтаксис foreach
даст вам нужные вам результаты и, вероятно, легче читать:
foreach (var x in someValues)
{
list.Add(x + 1);
}
Если вы непреклонны, вам нужно расширение Linq. это тривиально, чтобы реализовать это самостоятельно.
public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action)
{
foreach (var x in @this)
action(x);
}