为什么在使用 LINQ Sum 方法时出现异常 "Cannot implicitly convert type 'bool' to 'long?'" 以及如何修复它?

Why did I get an exception "Cannot implicitly convert type 'bool' to 'long?'" when using the LINQ Sum method and how to fix it?

我有以下有效的代码:

IEnumerable<Decimal?> values = getValues();

var sum = values.Where(x => x > 0).Sum();

但如果我尝试:

var sum = values.Sum(x => x > 0);

我收到错误:

Cannot implicitly convert type 'bool' to 'long?'

这不是应该在 Sum 或 Where 中应用过滤器吗?

确实,Sum 需要数字值而不是布尔值计算结果。

您需要先使用 Where or Select (not relevant here) then Sum 进行过滤:

var sum = values.Where(x => x != null && x > 0).Sum();

我添加了空检查,因为集合的类型是 decimal?

否则你需要这样写,但这不是速度优化:

var sum = values.Sum(x => x != null && x > 0 ? x : 0);

使用 selector 求和例如在具有 类、结构或元组时很有用:

var sum = controls.Sum(control => control.Width);

此代码:

var sum = values.Sum(x => x > 0);

包含一个 lambda 表达式(匿名函数),returns 一个 bool(真或假)。等同于:

var sum = values.Sum(x => Check(x));

private bool Check(long x)
{
    return x > 0;
}

由于您不能对 bool 求和,因此代码无效。 Sum() 如果传递的参数期望该参数是数字的枚举(例如 intlong,尽管它有许多重载)。

如您所见,here Enumerable.Sum 没有接受返回 Func 作为参数的布尔值的重载。它只有接受数字返回委托的重载。

这有什么用?

假设您有一个购物车中的商品列表,您想要计算总价,您可以这样做:

var totalPrice = cartItems.Sum(ci => ci.Price);

如果要先过滤,就得用Where.