Linq style “For Each”
Possible Duplicate:
Linq equivalent of foreach for IEnumerable
对于"for each"操作,是否有LINQ样式的语法?
例如,将基于一个集合的值添加到另一个已存在的集合:
1 2 3 4 5
| IEnumerable <int> someValues = new List <int>() { 1, 2, 3 };
IList <int> list = new List <int>();
someValues .ForEach(x => list .Add(x + 1)); |
而不是
1 2 3 4
| foreach(int value in someValues)
{
list.Add(value + 1);
} |
- StopExoal.COM/问题/ 200574/& Helip;
- 与这个问题有关,但不是很重复:stackoverflow.com/questions/858978/&hellip;
- 另请参阅Eric Lippert的博客文章,关于不在bcl中包含ForEach的理由:blogs.msdn.com/ericlippet/archive/2009/05/18/&hellip;
使用tolist()扩展方法是最好的选择:
1
| someValues.ToList().ForEach(x => list.Add(x + 1)); |
BCL中没有直接实现foreach的扩展方法。
虽然在Bcl中没有扩展方法,但是在EDCOX1的0个命名空间中仍然有一个选项…如果在项目中添加反应性扩展:
1 2 3
| using System.Reactive.Linq;
someValues.ToObservable().Subscribe(x => list.Add(x + 1)); |
这与上面使用EDCOX1〔1〕的结果相同,但在理论上是更有效的,因为它直接将值流到委托。
- 记住,对于一个很长的列表来说,这并不理想,因为它在循环遍历整个列表之前会复制整个列表。
- 调用ToList,然后调用ForEach,涉及对原始集合进行两次迭代。我希望任何时候都有一个标准的ForEach循环:更少的输入,更可读,更好的性能:foreach (var x in someValues) list.Add(x + 1);
- 对于任何一个看到这个并认为它是一个好答案的人来说,它不是。这是疯狂的低效。请看诺尔多林的回答,了解正确的做事方式。
- @史蒂夫:谢谢你指出这一点。实际上,这不是最好的解决方案,因为这意味着集合被迭代两次以上,内存被临时分配给List,从而增加了更多的开销!
- @斯特凡:不知道我的怎么不"正确"。您真的不想使用这种性能较差的方法,因为这样可以节省您编写3行扩展方法的时间。
- 总而言之,但我想补充一点:理论上这可能效率不高,但我所使用的大多数内存列表往往只有不到12个条目。珀尔夫问题通常在其他地方,所以我认为现在就断言这个答案不好是一个过早的优化。问题是这个语法是否可用,而且这与您在不编写扩展方法的情况下使用普通的.NET3.5SP1非常接近。我希望在BCL中有一个foreach扩展方法,但是它在当前框架中不可用。
- @马克:如果你的代码比其他代码更易读/更易懂/更直观,那么你的代码效率可能是可以原谅的,但事实并非如此。使用代码而不是标准的ForEach循环有什么好处?
- @卢克:没有什么特别的好处,但这也不是问题。无论如何,我认为这是小题大做:在大多数情况下,我打赌你根本感觉不到性能差异。
- 是的,如果更有效的解决方案不是那么简单的话,我也不会抱怨性能。(使用foreach循环或短扩展方法。)嗯,我也没有投反对票。
- 在我的测试中,MaxSeim-An的EDCOX1〔6〕的新答案似乎比EDCOX1、7和EDCX1 8的慢约50倍。
- "奎克,但从理论上讲,效率要高得多!;)
Array和List类已经有ForEach方法,尽管只有这个特定的实现。(顺便说一下,前者是static)。
不确定它是否真的比ForEach语句提供了很大的优势,但是您可以编写一个扩展方法来为所有IEnumerable对象完成这项工作。
1 2 3 4 5
| public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (var item in source)
action(item);
} |
这将允许您在问题中发布的确切代码按您的需要工作。
- 谢谢,很明显我可以自己写扩展。我只想在做这件事之前尽可能使用内置的东西。
- 是的,这很公平。我还确保我不会重新设计BCL功能。在这种情况下,却没有。
- 数组类没有foreach方法:),但有一个"EnumerableExtensions"stat?Microsoft.Practices.ObjectBuilder2命名空间中的C类。它具有用于IEnumerable的foreach方法:)
没有任何内置的功能,但您可以轻松创建自己的扩展方法来执行此操作:
1 2 3 4 5 6 7 8 9 10
| 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 );
}
} |
- 为什么没有内置的东西?我错过什么了吗?这似乎是非常需要的基本功能。
官方的ms行是"因为它不是一个功能操作"(即它是一个状态操作)。
你不能做点什么吗?
或者如果你真的需要它的话:
1
| var someValues = new List <int>( list .Select( x => x +1 ) ); |
- 您有一点关于功能性操作和状态性操作。然而,f_被设计为功能长度,并具有等效的ForEach方法。
- 你能给我一个"微软官方热线"的参考吗?我对他们剩下的作品感兴趣。
- 我可能不应该使用"官方"这个词,但这是我在想的博客:blogs.msdn.microsoft.com/ericlippert/2009/05/18/&hellip;
没有Linq ForEach扩展。但是,如果您愿意直接使用List,那么List类上有一个foreach方法。
就其价值而言,标准的ForEach语法将为您提供所需的结果,而且可能更容易阅读:
1 2 3 4
| foreach (var x in someValues)
{
list.Add(x + 1);
} |
如果您坚定不移,您需要一个Linq样式的扩展。自己实现这一点很简单。
1 2 3 4 5
| public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action)
{
foreach (var x in @this)
action(x);
} |
标准LINQ中没有类似的内容,但MoreLinq中有一个foreach运算符。