Call an Enumerated Average through an expression

I am trying to write dynamic code that performs some aggregations of Average, Sum, Max, etc.

For the im code to execute:

PropertyInfo sortProperty = typeof(T).GetProperty("PropertyName");

ParameterExpression parameter = Expression.Parameter(typeof(T), "p");


MemberExpression propertyAccess = Expression.MakeMemberAccess(parameter, sortProperty);
LambdaExpression orderByExp = Expression.Lambda(propertyAccess, parameter);

var exp = Expression.Lambda<Func<T, int>>(propertyAccess, parameter);

var call = Expression.Call(typeof(Enumerable), "Average", new[] { typeof(IEnumerable<T>) , typeof(Func<T, int>) }, parameter);

and I always get this exception:

There is no universal "Average" method of type "System.Linq.Enumerable" compatible with the arguments and arguments of the supplied type. No type arguments should be provided unless the method is general.

+4
source share
1 answer

Let's look at this line. Here you callCall

var call = Expression.Call(typeof(Enumerable), "Average", new[] { typeof(IEnumerable<T>) , typeof(Func<T, int>) }, parameter);

: " , ". IEnumerable<T> Func<T, int>, Average (TSource).

" Expression, ". , T, Average IEnumerable<TSource> Func<TSource, decimal> ( , , decimal).

, , , , :

PropertyInfo sortProperty = typeof(T).GetProperty("Prop");
ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
MemberExpression propertyAccess = Expression.MakeMemberAccess(parameter, sortProperty);

// parameter for the source collection
ParameterExpression source = Expression.Parameter(typeof(IEnumerable<T>), "source");

var exp = Expression.Lambda<Func<T, decimal>>(propertyAccess, parameter);
var call = Expression.Call(typeof(Enumerable), "Average", new[] {typeof(T)}, source, exp);

( ):

// assuming a class called T with a decimal property called Prop 
// because I'm a lazy and terrible person
var method = Expression.Lambda<Func<IEnumerable<T>, decimal>>(call, source).Compile();
var result = method(new List<T> {new T { Prop=10}, new T { Prop=20}});
// result is now 15
+3

All Articles