2011-06-12 84 views
3

我試圖用給定的類型和屬性名稱來構建屬性選擇器表達式。即t => t.PropertyName。動態屬性選擇器lambda函數

以下代碼編譯得很好,但結果爲空值。有人可以指出代碼中的錯誤嗎?

public static Expression<Func<T,object>> CreatePropSelectorExpression(string propName) where T:class,new() 
    { 
    var temp = Activator.CreateInstance<T>(); 
    ParameterExpression t = Expression.Parameter(typeof(T),"t"); 
    MemberExpression member = Expression.PropertyOrField(Expression.Constant(temp),propName); 
    return Expression.Lambda<Func<T,object>>(member,t); 
    } 

在此先感謝

+0

不要打擾。已經找到了解決方案。 需要使用成員表達式而不是臨時變量 – user759141 2011-06-12 07:06:59

回答

8

你實際上並不需要創建對象T,你只是創造一些表達式樹的一個實例。這一切都歸結到這真的:

Expression<Func<T, object>> CreatePropSelectorExpression<T>(string propertyName) 
{ 
    var parameter = Expression.Parameter(typeof(T)); 
    var body = Expression.Convert(Expression.PropertyOrField(parameter, propertyName), typeof(object)); 
    return Expression.Lambda<Func<T, object>>(body, parameter); 
} 
+0

Expression.Convert()的用途是什麼?它看起來像只適用於:var body = Expression.PropertyOrField(parameter,propertyName); – 0lukasz0 2013-03-23 16:55:01

+1

convert方法確保表達式具有某種類型。最終歸結爲演員陣容。如果屬性類型是「ValueType」,它將被要求,因爲它會變成一個裝箱操作。儘管在構建表達式時,最好儘可能生成預期類型的​​表達式。 – 2013-03-23 18:04:04

+0

好,但你可以提供一個嵌套的選擇器與IEnumerable propertyNames''作爲參數 – bradgonesurfing 2013-04-17 09:10:48

1

嵌套版本

static Expression<Func<R, O>> 
CreatePropSelectorExpression<R,O>(IEnumerable<string> propertyName) 
{ 
    ParameterExpression parameter = Expression.Parameter(typeof(R)); 
    Expression selector = propertyName 
     .Aggregate((Expression)parameter, 
       (a, name) => Expression.PropertyOrField(a, name)); 
    return Expression.Lambda<Func<R,O>>(selector, parameter); 
}