【问题标题】:C# and LINQ - arbitrary statement instead of letC# 和 LINQ - 任意语句而不是 let
【发布时间】:2015-02-12 20:56:53
【问题描述】:

假设我正在执行这样的 LINQ 查询(这是 LINQ to Objects,顺便说一句):

var rows = 
    from t in totals
    let name = Utilities.GetName(t)
    orderby name
    select t;

所以GetName 方法只是从Total 对象计算显示名称,并且是let 关键字的体面使用。但是假设我有另一种方法,Utilities.Sum(),它对Total 对象应用一些数学并在其上设置一些属性。我可以使用let 来实现这一点,如下所示:

var rows =
    from t in totals
    let unused = Utilities.Sum(t)
    select t;

这里奇怪的是Utilities.Sum() 必须返回一个值,即使我不使用它。如果它返回void,有没有办法在 LINQ 语句中使用它?我显然不能这样做:

var rows =
    from t in totals
    Utilities.Sum(t)
    select t;

PS - 我知道在 LINQ 表达式中调用具有副作用的方法可能不是的做法。只是想完全理解 LINQ 语法。

【问题讨论】:

  • 使用foreach,这就是它的用途。
  • 不确定为什么要使用 Utilities 对象来获取 tname 或 sum /b> object... Linq 提供以特定顺序获取数据或使用聚合函数的功能。我认为,您将访问数据的旧方法与新方法混合在一起。请注意,如果 TotalsUtilities 之间存在关系,您可以加入数据。
  • @MaciejLos 在我的示例中,Utilities 类是对同一对象的多个属性求和。 LINQ 中的Sum 方法对IEnumerable 中的一系列值求和。

标签: c# .net linq linq-to-objects


【解决方案1】:

不,没有对IEnumerable<T> 中的所有项目执行Action 的LINQ 方法。是very specifically left out,因为设计师不希望它出现在那里。

【讨论】:

  • 我不想对IEnumerable 执行操作。我想在 LINQ 语句中间放一个任意表达式。
  • @jonathanpeppers 你用不同的词来表达完全相同的事情。
【解决方案2】:

回答问题

不,但你可以通过创建一个 Func 来作弊,它只是调用预期的方法并吐出一个随机返回值,例如 bool

Func<Total, bool> dummy = (total) => 
    { 
        Utilities.Sum(total);
        return true;
    };

var rows = from t in totals
           let unused = dummy(t)
           select t;

但这不是一个好主意 - 它不是特别可读。


statement 在幕后

上述查询将转换为类似于以下内容的内容:

var rows = totals.Select(t => new { t, unused = dummy(t) })
                 .Select(x => x.t);

如果您想使用方法语法而不是查询语法,那么另一种选择是:

var rows = totals.Select(t =>
               {
                   Utilities.Sum(t);
                   return t;
               });

好一点,但仍在滥用 LINQ。


...但是你应该怎么做

但我真的认为没有理由不简单地单独循环总计:

foreach (var t in totals)
    Utilities.Sum(t);

【讨论】:

  • 如果你有多个unused变量怎么办?将它们命名为unused1unused2unused3...
  • 把这个改成where dummy(t)
  • @jonathanpeppers 您是否想通过将同事的代码变成难以处理的混乱来对同事进行恶作剧?
  • 是的,我要把变量命名为__1__2__3,如果需要的话,可以一直命名为 50。哈哈
【解决方案3】:

您应该从 Microsoft 的响应式扩展团队下载“交互式扩展”(NuGet Ix-Main)。它有很多有用的扩展。它会让你这样做:

var rows =
    from t in totals.Do(x => Utilities.Sum(x))
    select t;

它允许对遍历的枚举产生副作用。

【讨论】:

    【解决方案4】:

    请阅读我对该问题的评论。实现此类功能的最简单方法是使用如下查询:

    var rows = from t in totals
        group t by t.name into grp
        select new 
        {
            Name = t.Key,
            Sum = grp.Sum()
        };
    

    以上查询返回IEnumerable对象。

    更多信息请见:101 LINQ Samples

    【讨论】:

      猜你喜欢
      • 2023-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      相关资源
      最近更新 更多