2014-12-27 45 views
5

我試圖從一個字符串生成一個「屬性選擇器」。創建一個屬性選擇器從字符串表達式

讓我解釋一下我自己用活生生的例子了一下:

我們有一個名稱(字符串)屬性Person類。

我可以手動創建一個「屬性選擇」像這樣propertySelector寫作:

Expression<Func<Person, string>> propertySelector = x => x.Name; 

但我想用我的方法來獲得相同的屬性選擇器。

var propertySelector = CreatePropertySelectorExpression<Person, string>("Name"); 

我到目前爲止是這樣的:

public static Expression<Func<TIn, TOut>> CreatePropertySelectorExpression<TIn, TOut>(string path) 
{ 
    Expression exp = Expression.Parameter(typeof(TIn), "x"); 
    foreach (var property in path.Split('.')) 
    { 
     exp = Expression.PropertyOrField(exp, property); 
    } 
    return exp; 
} 

但是......我有和無效的轉換錯誤!

不能鍵入 'System.Linq.Expressions.Expression' 隱式轉換爲 'System.Linq.Expressions.Expression>'。一個 顯式轉換存在(是否缺少強制轉換?)

我很新的表現形式,我不知道該怎麼繼續:(

+0

請你能不能添加使用的一個真實的例子嗎? – InferOn 2014-12-27 18:05:46

+0

您的代碼中存在一些錯誤,例如Expression.Parameter將返回ParameterExpression,Expression.PropertyOrField將返回MemberExpression,真誠地,我不明白您會實現什麼 – InferOn 2014-12-27 18:11:42

+0

請檢查我剛纔編輯的編輯。我舉了一個更好的例子。也許代碼是錯誤的。我是表達式的新手:(提前致謝! – SuperJMN 2014-12-27 18:14:58

回答

12

exp只包含拉姆達的身體但你想要一個實際的拉姆達函數接受TIn類型存在的一個參數,所以你需要使用Expression.Lambda創建拉姆達:。

var param = Expression.Parameter(typeof(TIn)); 
var body = Expression.PropertyOrField(param, propertyName); 
return Expression.Lambda<Func<TIn, TOut>>(body, param); 

不過要注意的是,表達並不能真正幫助你多少你可能需要一個編福nction代替:

private static Func<TIn, TOut> CreatePropertyAccessor<TIn, TOut> (string propertyName) 
{ 
    var param = Expression.Parameter(typeof(TIn)); 
    var body = Expression.PropertyOrField(param, propertyName); 
    return Expression.Lambda<Func<TIn, TOut>>(body, param).Compile(); 
} 

然後,您可以使用它像這樣:

var name1 = CreatePropertyAccessor<Obj, string>("Name"); 
var name2 = CreatePropertyAccessor<Obj, string>("Name2"); 
var name3 = CreatePropertyAccessor<Obj, string>("Name3"); 

var o = new Obj() // Obj is a type with those three properties 
{ 
    Name = "foo", 
    Name2 = "bar", 
    Name3 = "baz" 
}; 

Console.WriteLine(name1(o)); // "foo" 
Console.WriteLine(name2(o)); // "bar" 
Console.WriteLine(name3(o)); // "baz" 
+0

只是哇!作品!謝謝! – SuperJMN 2014-12-27 18:27:20

相關問題