在my own question之后,我想到现在需要通过将Expression<Func<T, object>>
传递给我的方法来调用相同的服务和相同的方法。这是方法定义:
IList<T> List(params Expression<Func<T, object>>[] includeProperties);
这是我现在拥有的代码:
//Get generic type
var entityRelationType = typeof(Applicant).Assembly.GetType(string.Format("Permet.BackEnd.ETL.Domain.Models.{0}", tableRelation.RelationEntityName));
//create service that will receive the generic type
var definitionIService = typeof(IService<>).MakeGenericType(entityRelationType);
//instantiate the service using Unity (todo: fix singleton)
var serviceInstance = UnitySingleton.Container.Resolve(definitionIService, "");
//create the argument for the method that we invoke
var paramsType =
typeof(Expression<>).MakeGenericType(typeof(Func<,>)
.MakeGenericType(entityRelationType, typeof(object))).MakeArrayType();
#region Get Dynamic Data
ParameterExpression relationParameter = Expression.Parameter(entityRelationType, "");
//build the parameter that we want to pass to the method (Expression<Func<T, object>>
var include =
Expression.Lambda(
Expression.Property(relationParameter, tableRelation.NaviguationProprietyName),
relationParameter
);
dynamic datas = constructedIService
.GetMethod("List", new Type[] { paramsType }).Invoke(serviceInstance, new object[] { include });
包含成功创建了我认为是我的
Expression<Func<T, object>>
的lambda表达式(Param_0 => Param_0.Groupings)。但是,由于Param_0.Groupings实际上是一个IList,因此出现异常:类型为'System.Linq.Expressions.Expression
1[System.Func
2 [Permet.BackEnd.ETL.Domain.Models.CLLI,System.Collections.Generic.IList 1[Permet.BackEnd.ETL.Domain.Models.Grouping]]]' cannot be converted to type 'System.Linq.Expressions.Expression
1 [System.Func`2 [Permet.BackEnd。 ETL.Domain.Models.CLLI,System.Object]] []'。这基本上意味着我的
Expression<Func<CLLI, IList<Grouping>>>
无法在需要Expression<Func<CLLI, object>>
的方法中使用。如果我实际上直接致电我的服务:
IService<CLLI> clliService = new Service<CLLI>();
clliService.List(clli => clli.Groupings);
有用。
我将如何解决这个问题? IList不是对象吗?
最佳答案
问题是Expression<T>
是不变的,因此即使您可以将类型T
分配给类型U
,也不意味着可以将Expression<T>
分配给Expression<U>
。在您的情况下,T
是Func<CLI, IList<Grouping>>
,U
是Func<CLLI, object>
。
我认为唯一的解决方案是创建一个函数,将给定的表达式包装在Expression<Func<T, object>>
中,该函数委派给内部表达式并将结果转换为object
:
public static Expression<Func<T, object>> ConvertResult<T, TOut>(Expression<Func<T, TOut>> expr)
{
var paramExpr = Expression.Parameter(typeof(T));
var invokeExpr = Expression.Invoke(expr, paramExpr);
var castExpr = Expression.Convert(invokeExpr, typeof(object));
return Expression.Lambda<Func<T, object>>(castExpr, paramExpr);
}
关于c# - 通过传递Expression <Func <T,object >>来调用反射方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17578020/