我正在努力加深对副作用以及应如何控制和应用它们的理解。
在下面的航类列表中,我想为每个满足条件的航类设置一个属性:
IEnumerable<FlightResults> fResults = getResultsFromProvider();
//Set all non-stop flights description
fResults.Where(flight => flight.NonStop)
.Select(flight => flight.Description = "Fly Direct!");
在这个表达式中,我对我的列表有副作用。根据我有限的知识,我知道前。 “LINQ 仅用于查询”和“列表只有少数操作,分配或设置值不是其中之一”和“列表应该是不可变的” .
- 我上面的 LINQ 语句有什么问题,应该如何更改?
- 我在哪里可以获得有关我上述场景的基本范式的更多信息?
最佳答案
您有两种方法以 LINQ 方式实现它:
显式
foreach
循环foreach(Flight f in fResults.Where(flight => flight.NonStop)) f.Description = "Fly Direct!";
使用
ForEach
运算符,为副作用而设计:fResults.Where(flight => flight.NonStop) .ForEach(flight => flight.Description = "Fly Direct!");
对于这样一个简单的任务,第一种方式相当重,第二种方式只能用于非常短的 body 。
现在,您可能会问自己,为什么 LINQ 堆栈中没有 ForEach
运算符。这很简单——LINQ 应该是一种表达查询操作的函数式方式,这尤其意味着任何运算符都不应该有副作用。设计团队决定不向堆栈添加 ForEach
运算符,因为唯一的用途是它的副作用。
ForEach
运算符的通常实现如下所示:
public static class EnumerableExtension
{
public static void ForEach<T> (this IEnumerable<T> source, Action<T> action)
{
if(source == null)
throw new ArgumentNullException("source");
foreach(T obj in source)
action(obj);
}
}
关于C# 范式 : Side effects on Lists,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6386184/