我最近开始使用LINQ,它非常棒。我想知道,是否可以使用LINQ将一个函数(任何函数)应用于集合的所有元素,而无需使用foreach循环。就像Python中的Lambda函数一样。
例如,如果我有一个整数列表,我是否可以使用LINQ将常数添加到每个元素中。
如果我有一个数据库表,我能否使用LINQ为所有记录设置一个字段。
我正在使用C#。
常见的处理方法是在 IEnumerable<T>
上添加自己的 ForEach
泛型方法。这是我们在 MoreLINQ 中拥有的方法:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
source.ThrowIfNull("source");
action.ThrowIfNull("action");
foreach (T element in source)
{
action(element);
}
}
(ThrowIfNull
是任何引用类型的扩展方法,它会执行显而易见的操作。)
有趣的是看看这是否是.NET 4.0的一部分。它与LINQ的函数式风格相违背,但毫无疑问很多人发现它很有用。
一旦你掌握了它,你就可以编写像下面这样的代码:
people.Where(person => person.Age < 21)
.ForEach(person => person.EjectFromBar());
使用 LINQ 的惯用方法是处理集合并返回映射为所需格式的新集合。例如,要将常量添加到每个元素中,您需要类似于以下内容:
var newNumbers = oldNumbers.Select(i => i + 8);
以函数式的方式完成操作,而不是频繁地改变现有集合的状态,这样有助于将不同的操作分离开来,既容易阅读,又容易让编译器推理。
如果您需要对集合中的每个元素应用一项作用(具有与集合内容无关的副作用),那么LINQ并不是最适合的选择,尽管您可以使用Select
来模拟它(或者编写您自己的IEnumerable
扩展方法,就像许多人所做的那样)。在这种情况下,最好使用foreach
循环。
Select
存在问题,如果您不在结果上稍后进行迭代。 - Michel FeinsteinForEach
不会改变集合本身。它可以 - 并且通常用于 - 编辑集合中的元素。个人而言,我将编辑后的集合作为结果返回,但您的情况可能有所不同。 - Suncat2000如果您不关心顺序,更在意为每个项目完成任务,您还可以考虑并行处理:
SomeIEnumerable<T>.AsParallel().ForAll( Action<T> / Delegate / Lambda )
例如:var numbers = new[] { 1, 2, 3, 4, 5 };
numbers.AsParallel().ForAll( Console.WriteLine );
希望对你有所帮助。
哈哈,伙计,我几个小时前刚刚问了这个问题(差不多)……试试这个:
示例:
someIntList.ForEach(i=>i+5);
ForEach()
是 .NET 中的一个内置方法。
这会修改列表,而不是返回一个新的列表。
.ToList().ForEach(...)
就足够了。 - Tod或者你可以对其进行黑客攻击。
Items.All(p => { p.IsAwesome = true; return true; });
如果集合不支持 ForEach
,您可以使用 Parallel
类中的静态 ForEach
方法:
var options = new ParallelOptions() { MaxDegreeOfParallelism = 1 };
Parallel.ForEach(_your_collection_, options, x => x._Your_Method_());
var foo = (from fooItems in context.footable select fooItems.fooID + 1);
返回id的列表+1,您可以使用一个函数来处理select子句中的任何内容。
更新:根据Jon Skeet的建议,这是我刚刚发布的代码片段的更好版本:
var foo = context.footable.Select(foo => foo.fooID + 1);
我找到了一些方法来在包含我的自定义类方法的字典中执行它们。
foreach (var item in this.Values.Where(p => p.IsActive == false))
item.Refresh();
'this' 是从哪里派生的:Dictionary<string, MyCustomClass>
class MyCustomClass
{
public void Refresh(){}
}
Where
部分是功能性的...但是ForEach
部分不太是,我个人认为。 - Jon Skeet