Sum扩展方法对含null元素的集合会抛NullReferenceException,需用Where过滤或??0兜底;仅支持数值类型求和,string等非数值类型需转为数值属性;性能上for循环通常优于Sum。
Sum扩展方法对null元素会直接抛异常
只要List里有
,又对引用类型属性调用
,运行时立刻报
。这不是设计缺陷,而是Linq默认不帮你做空值防御——它假设你清楚数据状态。
安全做法是先过滤:
如果属性本身可能为
(比如
),得用
兜底:
注意
在前还是
在前:先
能减少计算量;但若集合很大且
极少,
反而更简洁
Sum不能直接用于string或自定义类型字段
只重载了数值类型(
、
、
等)的委托签名。传
这种int属性可以,但传
本身会编译失败。
错误写法:
→ 编译报错:
正确写法:
或
(后者要求
是
数组之类)
自定义类型要支持求和,得自己实现
运算符重载,并确保委托返回类型匹配
的泛型约束
性能差异:Sum vs for循环遍历累加
对小列表(Sum()因额外的枚举器开销和委托调用,比裸
慢10%–30%。
C知道
CSDN推出的一款AI技术问答工具
下载
高频调用场景(如游戏帧更新、实时计算)建议用
:
优势在可读性和链式组合,比如
,此时别为了微小性能牺牲表达力
注意
的
是O(1),但
的
会强制枚举全部元素,无法提前退出
浮点数求和的精度陷阱
和
用
累加时,顺序不同结果可能不同——这不是Bug,是IEEE 754浮点规则决定的。
例如:
结果是
,而数学上应为
关键点:Linq的
按迭代顺序累加,不重排;需要高精度时改用
类型字段,或引入Kahan求和算法
数据库查询后用
再算一次?小心双重精度丢失——最好让SQL Server/PostgreSQL在服务端完成求和
实际用的时候,最容易被忽略的是null检查和浮点累积误差。前者导致崩溃,后者导致结果不对但还不容易发现。
nullSum()NullReferenceExceptionlist.Where(x => x != null).Sum(x => x.Amount)nulldecimal??? 0list.Sum(x => x?.Amount ?? 0)WhereSumWherenullSum(x => x?.Amount ?? 0)Sum()intdoubledecimalstring.Lengthstringlist.Sum(x => x.Name)Cannot convert lambda expression to delegate because some of the return types in the block are not implicitly convertible to the delegate return typelist.Sum(x => x.Name.Length)list.Select(x => x.Name).Sum()Nameint+Sumforforfor (int i = 0; i Sum()list.Where(...).OrderBy(...).Sum(...)ListCountIEnumerableSum()floatdoubleSum()new List { 1e20f, 1.0f, -1e20f }.Sum() 01.0fSum()decimalSum()