Average()仅适用于数值类型数组,空数组抛InvalidOperationException,可空类型需防null;手写循环性能更优且可控。

Average 扩展方法能直接算数组平均值,但前提是数组元素类型支持数值运算且非空——空数组会抛 InvalidOperationException。
用 Average() 前先确认类型和数据状态
不是所有数组都能直接调用 Average():它只对实现了 IEnumerable<T> 且 T 是数值类型(如 int、double、decimal)的集合有效。比如 string[] 或自定义类数组会编译失败。
- 常见错误现象:
CS1061: 'string[]' does not contain a definition for 'Average' - 使用场景:处理
int[]、double[]、decimal[]等原生数值数组最稳妥 - 空数组必须提前检查,否则运行时崩在
InvalidOperationException: Sequence contains no elements - 示例:
int[] nums = { 1, 2, 3 }; var avg = nums.Average(); // 返回 2.0
遇到 Nullable<T> 类型(如 int?)要小心过滤
Average() 对可空数值类型默认自动跳过 null 值,但结果类型变成 double?(即使输入是 int?),且仍可能返回 null —— 当所有元素都是 null 时。
- 参数差异:
int?[] arr = { 1, null, 3 }; arr.Average() → 2.0;int?[] arr2 = { null, null }; arr2.Average() → null - 容易踩的坑:直接解包
.Value会触发NullReferenceException - 安全写法:
var avg = arr.Average() ?? 0;或先Where(x => x.HasValue).Select(x => x.Value).Average()
性能和兼容性:LINQ vs 手写循环
对小数组或一次性计算,Average() 简洁可靠;但高频调用或超大数组时,手写循环略快(省去枚举器开销和装箱)。
- 兼容性影响:需要引用
System.Linq,.NET Framework 3.5+ / .NET Core 1.0+ 都支持 - 性能关键点:
Average()内部遍历两次(一次计数、一次求和),而手写循环只需一次遍历 - 示例对比:
double avg = nums.Length == 0 ? 0 : nums.Sum() / (double)nums.Length;更可控,也避免异常
最常被忽略的是空数组和 null 元素的边界处理——生产代码里别依赖“数据肯定不为空”这种假设。










