.NET 7泛型数学中Linq Sum方法为何无法编译?
问题:泛型Average方法编译失败(.NET 7 RC1 + VS 17.4 Preview 2.1)
问题代码与报错
初始代码
using System.Numerics; int averageInt = Average<int, int>(1, 5, 10); Console.WriteLine(averageInt); double averageDouble = Average<int, double>(1, 5, 10); Console.WriteLine(averageDouble); TResult Average<TInput, TResult>(params TInput[] numbers) where TInput : INumber<TInput> where TResult : INumber<TResult> => numbers.Sum() / TResult.CreateChecked(numbers.Length);
编译报错
Error CS1929 'TInput[]' does not contain a definition for 'Sum' and the best extension method overload 'Queryable.Sum(IQueryable<decimal>)' requires a receiver of type 'IQueryable<decimal>'
尝试修改后的代码
using System.Numerics; int averageInt = Average<int, int>(1, 5, 10); Console.WriteLine(averageInt); double averageDouble = Average<int, double>(1, 5, 10); Console.WriteLine(averageDouble); TResult Average<TInput, TResult>(params TInput[] numbers) where TInput : INumber<TInput> where TResult : INumber<TResult> => numbers.AsQueryable().Sum() / TResult.CreateChecked(numbers.Length);
二次报错
Error CS1929 'IQueryable<TInput>' does not contain a definition for 'Sum' and the best extension method overload 'Queryable.Sum(IQueryable<decimal>)' requires a receiver of type 'IQueryable<decimal>'
问题原因
- 缺少LINQ命名空间:
Sum是System.Linq.Enumerable类提供的扩展方法,代码未引入System.Linq,导致编译器找不到匹配的Sum重载。 - 不必要的IQueryable转换:转为
IQueryable后,Queryable.Sum的泛型重载不支持未指定具体数值类型的TInput,反而加剧类型匹配问题。 - 类型转换缺失:
numbers.Sum()返回TInput类型,直接与TResult类型的长度转换值做除法,存在类型不兼容问题。
修复后的代码
using System.Numerics; using System.Linq; // 引入LINQ命名空间 int averageInt = Average<int, int>(1, 5, 10); Console.WriteLine(averageInt); double averageDouble = Average<int, double>(1, 5, 10); Console.WriteLine(averageDouble); TResult Average<TInput, TResult>(params TInput[] numbers) where TInput : INumber<TInput> where TResult : INumber<TResult> => TResult.CreateChecked(numbers.Sum()) / TResult.CreateChecked(numbers.Length);
修复说明
- 新增
using System.Linq;:让编译器找到支持INumber<T>类型的Enumerable.Sum<TInput>扩展方法。 - 移除
AsQueryable()转换:直接使用数组的Sum()方法,避免Queryable的类型匹配限制。 - 用
TResult.CreateChecked()包裹numbers.Sum():将TInput类型的总和安全转换为TResult类型,确保除法操作的类型兼容性,同时提供溢出检查。
内容的提问来源于stack exchange,提问作者Boris Eetgerink
相关产品推荐
相关产品推荐

