簡體   English   中英

通過傳遞一個表達式來調用使用反射的方法 <Func<T, object> &gt;

[英]Invoke a method using reflection by passing an Expression<Func<T, object>>

根據我自己的問題 ,我想到現在需要通過將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 });

包含成功創建了我的lambda表達式(Param_0 => Param_0.Groupings),我相信這將是我的Expression<Func<T, object>> 但是,由於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>是不變的,因此即使您具有可以分配給類型U T類型,也不意味着可以將Expression<T>分配給Expression<U> 在您的情況下, TFunc<CLI, IList<Grouping>>UFunc<CLLI, object>

我認為唯一的解決方案是創建一個函數,將給定的表達式包裝在Expression<Func<T, 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM