2012-03-29 21 views
3

Ich bin eine allgemeine Setter mit Ausdrucksbaum zu schaffen und hier ist mein CodeParameterexpression des Typs ‚System.Int32‘ kann nicht für die Delegierten Parameter des Typs verwendet werden ‚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); 
} 

ich nicht Rufen Sie in der obigen Methode .Compile() auf, weil ich den Ausdruck untersuchen möchte, den es erstellt.

Und mein Ziel ist

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

} 

ich die Methode wie diese i das Alter passieren

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

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

Der Grund

nennen als String ist, wird i von XML diesen Wert zu bekommen.

Es erstellt Aktion für FirstName ohne Fehler, während für Age es bläst.

Fehler passiert in dieser Zeile für Age:

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

Fehler:

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

Kann ich etwas tun, mit dynamischer ..?

Ich hoffe, jemand wird eine Lösung haben. Dank

+1

Warum würden Sie nicht nur das Alter in einen int geworfen, bevor er auf die Aktion vorbei? –

Antwort

3

Sie sollten Convert.ChangeType für Typumwandlung nennen:

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

Ehrfürchtig. Es klappt. Danke, Balazs Tihanyi. – kans

+1

Ich bin froh, dass es dir geholfen hat. Vergessen Sie nicht, es als akzeptierte Antwort zu markieren. –

2

Das Problem ist folgendes:

Sie sind ein Expression<Action<T,string>> Rückkehr, was im Grunde bedeutet, dass das Ergebnis ein string sein wird. Auf der anderen Seite geben Sie "Alter" als Name des Feldes ein, das die Aktion zurückgeben soll. Age ist jedoch vom Typ int, nicht string.

Sie können dieses Problem lösen zumindest zwei Möglichkeiten:

  1. einen zweiten generischen Parameter auf Ihre GetAction Methode hinzu, die den Rückgabetyp angibt.
  2. Fügen Sie einen Aufruf von ToString für die zurückgegebene Eigenschaft zu dem Ausdruck hinzu.
Verwandte Themen