gpt4 book ai didi

c# - 通过传递 Expression> 使用反射调用方法

转载 作者:太空宇宙 更新时间:2023-11-03 13:39:34 25 4
gpt4 key购买 nike

正在关注 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 });

include 成功地创建了我的 lambda 表达式 (Param_0 => Param_0.Groupings),我认为它是我的 Expression<Func<T, object>> .然而,由于 Param_0.Groupings 实际上是一个 IList,我得到一个异常(exception):

Object of type 'System.Linq.Expressions.Expression1[System.Func2[Permet.BackEnd.ETL.Domain.Models.CLLI,System.Collections.Generic.IList1[Permet.BackEnd.ETL.Domain.Models.Grouping]]]' cannot be converted to type 'System.Linq.Expressions.Expression1[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> .在你的情况下,TFunc<CLI, IList<Grouping>>UFunc<CLLI, object> .

我认为唯一的解决方案是创建一个函数来将给定的表达式包装在 Expression<Func<T, object>> 中它委托(delegate)给内部表达式并将结果转换为 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com