2012-03-29 86 views
3

我使用表達式樹創建一個一般的setter和這裏的委託參數是我的代碼ParameterExpression不能被用於類型「System.String」

public Expression<Action<T,string>> GetAction<T>(string fieldName) 
{ 
    ParameterExpression targetExpr = Expression.Parameter(typeof(T), "Target"); 
    MemberExpression fieldExpr = Expression.Property(targetExpr, fieldName);  
    ParameterExpression valueExpr = Expression.Parameter(fieldExpr.Type, "value"); 
    UnaryExpression valueCast = (!fieldExpr.Type.IsValueType) 
           ? Expression.TypeAs(valueExpr, fieldExpr.Type) 
           : Expression.Convert(valueExpr, fieldExpr.Type); 
    BinaryExpression assignExpr = Expression.Assign(fieldExpr, valueCast);  
    return Expression.Lambda<Action<T, string>>(assignExpr, targetExpr, valueExpr); 
} 

我不在上面的方法中調用.Compile(),因爲我想檢查它構建的表達式。

而我的目標是

class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int Age { get; set; } 

} 

我調用該方法是這樣

var lastname = GetAction<Person>("FirstName"); 
var age = GetAction<Person>("Age"); 

lastname.Compile()(p, "Solutions"); 
age.Compile()(p, "10"); 

我之所以傳遞年齡字符串,我會越來越從XML此值。

它正在創建FirstName的行動沒有任何錯誤,而對於Age它吹。

錯誤發生在這一行Age

return Expression.Lambda<Action<T, string>>(assignExpr, targetExpr, valueExpr); 

錯誤:

ParameterExpression of type 'System.Int32' cannot be used for delegate parameter of type 'System.String'

我可以做動態的東西..?

我希望有人會有一些解決方案。由於

+1

你爲什麼不只是將它傳遞給操作之前投的年齡爲int? – 2012-03-29 14:40:51

回答

3

你應該叫Convert.ChangeType進行類型轉換:

public static Expression<Action<T, string>> GetAction<T>(string fieldName) 
{ 
    ParameterExpression targetExpr = Expression.Parameter(typeof(T), "Target"); 
    MemberExpression fieldExpr = Expression.Property(targetExpr, fieldName); 
    ParameterExpression valueExpr = Expression.Parameter(typeof(string), "value"); 
    MethodCallExpression convertExpr = Expression.Call(typeof(Convert), 
     "ChangeType", null, valueExpr, Expression.Constant(fieldExpr.Type)); 
    UnaryExpression valueCast = Expression.Convert(convertExpr, fieldExpr.Type); 
    BinaryExpression assignExpr = Expression.Assign(fieldExpr, valueCast); 
    return Expression.Lambda<Action<T, string>>(assignExpr, targetExpr, valueExpr); 
} 
+1

太棒了。有用。謝謝Balazs Tihanyi。 – kans 2012-03-30 07:06:46

+1

我很高興它幫助你。請不要忘記將其標記爲已接受的答案。 – 2012-03-30 20:52:47

2

的問題如下:

您正在返回一個Expression<Action<T,string>>,這基本上意味着,其結果將是一個string。另一方面,您傳遞的是「年齡」作爲該行爲應該返回的字段的名稱。 Age然而是int類型,而不是string

可以在至少兩種方式解決這個問題:

  1. 添加第二個泛型參數到您的GetAction方法指定的返回類型。
  2. 將返回屬性上的ToString添加到表達式中。
相關問題