使用表达式得到一个获取属性的Acessor(Using Expressions to get a G

2019-10-18 17:36发布

我希望得到一个属性(的获取Acessor PropertyInfo ),并将其编译成一个Func<object,object> 。 声明类型仅在运行时知道。

我当前的代码是:

public Func<Object, Object> CompilePropGetter(PropertyInfo info)
{
    MethodInfo getter = info.GetGetMethod();

    ParameterExpression instance = Expression.Parameter(info.DeclaringType, info.DeclaringType.Name);

    MethodCallExpression setterCall = Expression.Call(instance, getter);

    Expression getvalueExp = Expression.Lambda(setterCall, instance);


    Expression<Func<object, object>> GetPropertyValue = (Expression<Func<object, object>>)getvalueExp;
    return GetPropertyValue.Compile();

}

不幸的是,我必须把<Object,Object>作为通用参数,因为有时我将获得的属性Type等, typeof(T).GetProperties()[0].GetProperties()其中第一的GetProperties()[ ]返回一个定制类型的对象,我必须反映它。

当我运行上面的代码,我得到这个错误:

Unable to cast object of type 'System.Linq.Expressions.Expression`1[System.Func`2[**CustomType**,**OtherCustomType**]]' to type 'System.Linq.Expressions.Expression`1[System.Func`2[System.Object,System.Object]]'.

所以,我能做些什么来返回Func<Object,Object>

Answer 1:

您可以添加类型转换预期的类型和使用的返回类型Expression.Convert

public static Func<Object, Object> CompilePropGetter(PropertyInfo info)
{
    ParameterExpression instance = Expression.Parameter(typeof(object));
    var propExpr = Expression.Property(Expression.Convert(instance, info.DeclaringType), info);
    var castExpr = Expression.Convert(propExpr, typeof(object));
    var body = Expression.Lambda<Func<object, object>>(castExpr, instance);
    return body.Compile();
}


文章来源: Using Expressions to get a Get Acessor of a property