您可以通过使用开放式泛型类型定义,然后从中创建特定类型来实现此操作:
typeof(Func<,>).MakeGenericType(typeof(int), orderType);
然而,您正在尝试的操作(调用 Lambda<TDelegate>
)是不直接可能的。您必须不带类型参数调用 Lambda
:
var propertyinfo = typeof(T).GetProperty(sortExpressionStr);
Type orderType = propertyinfo.PropertyType;
var param = Expression.Parameter(typeof(T), "x");
var sortExpression = Expression.Lambda(
Expression.Convert(Expression.Property(param, sortExpressionStr),
orderType),
param));
这将在幕后为您创建适当的
Func<,>
。如果您想编译表达式并使用委托,您只能通过动态方式执行此操作。
sortExpression.Compile().DynamicInvoke(param)
如果您想在
Queryable
上调用
OrderBy
扩展方法,事情会变得有些复杂:
var propertyInfo = typeof(T).GetProperty(sortExpressionStr);
Type orderType = propertyInfo.PropertyType;
// first find the OrderBy method with no types specified
MethodInfo method = typeof(Queryable).GetMethods()
.Where(m => m.Name == "OrderBy" && m.GetParameters().Length == 2)
.Single();
// then make the right version by supplying the right types
MethodInfo concreteMethod = method.MakeGenericMethod(typeof(T), orderType);
var param = Expression.Parameter(typeof(T), "x");
// the key selector for the OrderBy method
Expression orderBy =
Expression.Lambda(
Expression.Property(orderParam, propertyInfo),
orderParam);
// how to use:
var sequence = new T[0].AsQueryable(); // sample IQueryable
// because no types are known in advance, we need to call Invoke
// through relection here
IQueryable result = (IQueryable) concreteMethod.Invoke(
null, // = static
new object[] { sequence, orderBy });
sortExpression
是类型为Expression<Func<T,orderType>>
的,因为orderType
只有在运行时才能确定,而不是在编译时。你打算如何在编译后使用你的 lambda 表达式呢? - dtb