【问题标题】:C# Get Method by reflection with Expression<Func<TEntity,object>> in ParameterC# 通过参数中的 Expression<Func<TEntity,object>> 反射获取方法
【发布时间】:2017-07-14 17:57:21
【问题描述】:

我是反思的新手,希望你能帮助我。我发现了很多与我类似的问题,但没有在我的问题中得到传播。

我有一个方法:

IEnumerable<TEntity> Get<TEntity>(Expression<Func<TEntity, object>> propertyNameExpression, object propertyValue) where TEntity : NT.Base.Framework.ODL.Entity;

我通常这样称呼这个方法: PersistentService.Get&lt;Agent&gt;(a =&gt; a.ID, Guid.Empty);

但现在我只在运行时知道我有哪个类。所以我有一个

Type classType;

并且需要知道如何用classType调用这个方法。我有一个临时解决方案,我采用带有字符串的方法,但代码中的硬编码字符串不太好。

MethodInfo methodInfo = typeof(PersistenceService).GetMethod("Get", new Type[] { classType, typeof(string) });
var classMethod = methodInfo.MakeGenericMethod(classType);
string query = "SELECT * FROM " + classType.Name + " WHERE " + classType.Name + ".Id = '" + pg.GUID.ToString() + "'";
dynamic dEnumeration = classMethod.Invoke(PersistenceService, new object[] { query });
dynamic dEntity = Enumerable.FirstOrDefault(dEnumeration);

编辑:我尝试了以下方法,但 methodInfo 始终为 NULL

ParameterExpression parameter = Expression.Parameter(typeof(Entity), "a");         
var delegateType = typeof(Func<,>).MakeGenericType(typeof(Entity), typeof(object));                        
var yourExpression = Expression.Lambda(delegateType, parameter, parameter);                        
MethodInfo methodInfo = typeof(PersistenceService).GetMethod("Get", new Type[] { yourExpression.GetType(), typeof(object) });

yourExpression.GetType() 的类型是:

{Name = "Expression`1" FullName = "System.Linq.Expressions.Expression`1[[System.Func`2[[NT.Base.Framework.ODL.Entity, NT.Base.Framework.ODL, Version=0.0.0.126, Culture=neutral, PublicKeyToken=null],[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"}    System.Type {System.RuntimeType}

所以请帮助我,如何获取和调用此方法。

【问题讨论】:

  • 您需要使用Expression API 来构建表达式树。
  • 我编辑了这个问题,我尝试了什么,但它并没有解决我的问题。

标签: c# reflection expression func


【解决方案1】:

我自己弄的:

ParameterExpression parameter = Expression.Parameter(classType, "a");

//a.Id GUID
MemberExpression property = Expression.Property(parameter, "Id");
//a.ID as object
var newProp = Expression.TypeAs(property, typeof(object));
var delegateType = typeof(Func<,>).MakeGenericType(classType, typeof(object));
var yourExpression = Expression.Lambda(delegateType, newProp, parameter);

MethodInfo methodInfo = typeof(PersistenceService).GetMethods()
.Where(x => x.Name == "Get")
.Select(x => new { M = x, P = x.GetParameters() })
.Where(x => x.P.Length == 2
            && x.P[0].ParameterType.IsGenericType
            && x.P[0].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)                             
            && x.P[1].ParameterType == typeof(object))
.Select(x => new { x.M, A = x.P[0].ParameterType.GetGenericArguments() })
.Where(x => x.A[0].IsGenericType
            && x.A[0].GetGenericTypeDefinition() == typeof(Func<,>))
.Select(x => new { x.M, A = x.A[0].GetGenericArguments() })
.Where(x => x.A[0].IsGenericParameter
            && x.A[1] == typeof(object))
.Select(x => x.M)
.SingleOrDefault();

if(methodInfo != null)
{
    MethodInfo method = methodInfo.MakeGenericMethod(classType);
    dynamic dEnumeration = method.Invoke(PersistenceService, new object[] { yourExpression, pg.GUID });
    dynamic dEntity = Enumerable.FirstOrDefault(dEnumeration);
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    相关资源
    最近更新 更多