使用表达式获取属性的获取方式 [英] Using Expressions to get a Get Acessor of a property

查看:128
本文介绍了使用表达式获取属性的获取方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取一个Property的Get 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);

表达式getvalueExp = Expression.Lambda(setterCall,instance);


表达式< Func< object,object>> GetPropertyValue =(Expression< Func< object,object>>)getvalueExp;
返回GetPropertyValue.Compile();

}

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



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

 无法转换类型为'System.Linq.Expressions.Expression`1的对象[System.Func`2 [** CustomType **,** OtherCustomType **]]键入'System.Linq.Expressions.Expression`1 [System.Func`2 [System.Object的,System.Object的]]。 

所以,我可以做些什么来返回一个 Func< Object,Object>

解决方案

您可以使用 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();
}


I want to get the Get Acessor of a Property (PropertyInfo) and compile it to a Func<object,object>. The declaring type is only known at runtime.

My current code is:

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();

}

Unfortunately, I have to put <Object,Object> as generic parameters, because sometimes I will get the properties of a Type, like typeof(T).GetProperties()[0].GetProperties(), where the first GetProperties()[] returns a custom-type object, and I have to reflect it.

When I run the code above, I get this error:

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]]'.

So, what can I do to return a Func<Object,Object>?

解决方案

You can add casts to the expected type and from the return type using 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();
}

这篇关于使用表达式获取属性的获取方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆