2012-03-29 13 views
3

私はここで式ツリーを用いた一般的なセッターを作成してるのデリゲートパラメータのために使用することはできませんが、私のコード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()と呼びます。なぜなら、それが構築する式を調べたいからです。

そして、私のオブジェクトは、私が文字列として年齢を渡す理由は、私はXMLからこの値を取得します。この

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

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

のようなメソッドを呼び出す

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

} 

です。

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に年齢をキャストではないでしょうか? –

答えて

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

+1

それがあなたを助けてくれてうれしいです。それを受け入れられた答えとしてマークすることを忘れないでください。 –

2

問題は以下の通りです:あなたは基本的に結果はstringになることを意味し、Expression<Action<T,string>>を戻ってきている

。一方、アクションが返すフィールドの名前として "Age"を渡しています。 Ageは、タイプintであり、ではありません。

あなたは、少なくとも2つの方法でこの問題を解決することができます。

  1. は、戻り値の型を指定し、あなたのGetAction方法に2つ目の一般的なパラメータを追加します。
  2. 返されたプロパティのToStringへの呼び出しを式に追加します。
関連する問題