C# 范式 : Side effects on Lists

标签 c# linq list paradigms side-effects

我正在努力加深对副作用以及应如何控制和应用它们的理解。

在下面的航类列表中,我想为每个满足条件的航类设置一个属性:

IEnumerable<FlightResults> fResults = getResultsFromProvider();

//Set all non-stop flights description
fResults.Where(flight => flight.NonStop)
        .Select(flight => flight.Description = "Fly Direct!");

在这个表达式中,我对我的列表有副作用。根据我有限的知识,我知道前。 “LINQ 仅用于查询”和“列表只有少数操作,分配或设置值不是其中之一”和“列表应该是不可变的” .

  • 我上面的 LINQ 语句有什么问题,应该如何更改?
  • 我在哪里可以获得有关我上述场景的基本范式的更多信息?

最佳答案

您有两种方法以 LINQ 方式实现它:

  1. 显式foreach 循环

    foreach(Flight f in fResults.Where(flight => flight.NonStop))
      f.Description = "Fly Direct!";
    
  2. 使用 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/

相关文章:

c# - (反)序列化时出现 "Binary stream does not contain a valid BinaryHeader"错误?

c++ - 类列表的 vector 中的值不被修改

Python按顺序减少列表

c# - 扩展方法需要将类声明为静态

c# - 使用没有魔术字符串的 ViewModels 的 MVC 下拉列表

c# - 如何在不对列进行硬编码的情况下在 LINQ 中转换数据

c# - 为什么我的 linq 别名超出范围?

LINQ 的 SQL 命令(旋转)

string - 从字符串列表中查找公共(public)子字符串

c# - 从 Win32 图标指针创建 Direct2D BitmapSource