I have the following code, but it does not compile in Visual Studio 17.4 preview 2.1 and .NET 7 RC1 SDK:
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);
The compiler error I get is:
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>'
I tried the following as an alternative, but it also doesn't compile:
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);
With the error:
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>'
What am I missing here?
CodePudding user response:
ATM there is no overload for Enumerable.Sum
(as for Max
, Min
etc.) leveraging the generic math. For now you can work around this fact using Enumerable.Aggregate
:
TResult Average<TInput, TResult>(params TInput[] numbers)
where TInput : INumber<TInput>
where TResult : INumber<TResult> => TResult.CreateChecked(numbers.Aggregate(TInput.Zero, (agg, t) => agg t)) / TResult.CreateChecked(numbers.Length);
The same approach can be used for other similar opeartions.
For build in support - monitor this github issue.