Linq风格的“For each”;

“for each”操作是否有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);
}
502374 次浏览

使用ToList()扩展方法是最好的选择:

someValues.ToList().ForEach(x => list.Add(x + 1));

在BCL中没有直接实现ForEach的扩展方法。


虽然在基类库中没有扩展方法可以做到这一点,但在System命名空间中仍然有选项…如果你在你的项目中添加反应性的扩展:

using System.Reactive.Linq;


someValues.ToObservable().Subscribe(x => list.Add(x + 1));

这与上面使用ToList的结果相同,但(理论上)更有效,因为它直接将值流式传输给委托。

在标准Linq中没有类似的东西,但在MoreLinq中有一个ForEach操作符。

ArrayList<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);
}

这将允许您在问题中发布的确切代码按照您想要的方式工作。

它没有任何内置的东西,但你可以很容易地创建自己的扩展方法来做它:

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);
}
}

微软官方的说法是“因为它不是一个功能性操作”(即它是一个有状态操作)。

你就不能这样做吗:

list.Select( x => x+1 )

或者如果你真的需要一个列表:

var someValues = new List<int>( list.Select( x => x+1 ) );

没有Linq ForEach扩展。然而,如果你愿意直接使用ListList类在它上面有一个ForEach方法。

不管怎样,标准的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);
}