我正在尝试编写动态代码来执行一些聚合,包括Average,Sum,Max等。
这是我正在执行的代码:
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);
我总是得到那个例外:
类型'System.Linq.Enumerable'上没有泛型方法'Average'与提供的类型参数和参数兼容。如果方法是非泛型的,则不应提供类型参数。
答案 0 :(得分:3)
让我们来看看这一行。在这里,您正在呼叫Call
var call = Expression.Call(typeof(Enumerable), "Average", new[] { typeof(IEnumerable<T>) , typeof(Func<T, int>) }, parameter);
第三个参数是“Type对象的数组,用于指定泛型方法的类型参数。”。您传递的是IEnumerable<T>
和Func<T, int>
类型,但是Average
takes only a single type parameter (TSource
)。
第四个参数是“Expression对象的数组,表示方法的参数。”。您传递的表达式代表T
,但Average
需要IEnumerable<TSource>
和Func<TSource, decimal>
(或者您要调用的任何重载,我只会使用{ {1}}一个例子)。
我不知道您的最终目标是使用此代码,但它可能应该如下所示:
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);