2013-10-04 35 views
1

我想獲取屬性的獲取處理器(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>

回答

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