2010-02-04 11 views
49

Ich versuche ein einfaches Skript-System zu erstellen, das zum Drucken von Etiketten verwendet wird. Ich habe dies in der Vergangenheit mit Reflektion ohne Probleme getan, aber ich versuche es jetzt mit Lambda-Funktionen, damit ich die Funktionen zur Wiederverwendung zwischenspeichern kann.Ausdruck des Typs 'System.Int32' kann nicht für den Rückgabetyp 'System.Object' verwendet werden

Der Code, den ich bisher habe, ist wie folgt ...

public static string GetValue<T>(T source, string propertyPath) { 

    try { 

     Func<T, Object> func; 

     Type type = typeof(T); 
     ParameterExpression parameterExpression = Expression.Parameter(type, @"source"); 
     Expression expression = parameterExpression; 
     foreach (string property in propertyPath.Split('.')) { 
      PropertyInfo propertyInfo = type.GetProperty(property); 
      expression = Expression.Property(expression, propertyInfo); 
      type = propertyInfo.PropertyType; 
     } 

     func = Expression.Lambda<Func<T, Object>>(expression, parameterExpression).Compile(); 

     object value = func.Invoke(source); 
     if (value == null) 
      return string.Empty; 
     return value.ToString(); 

    } 
    catch { 

     return propertyPath; 

    } 

} 

Dies scheint in einigen Fällen zu arbeiten, aber in anderen ist es nicht. Das Problem scheint in meinem Versuch zu sein, die Werte als Objekte zurückzugeben - unabhängig von den tatsächlichen Datentypen. Ich versuche dies zu tun, weil ich zur Kompilierzeit nicht weiß, was der Datentyp sein wird, aber auf lange Sicht brauche ich nur eine Zeichenkette.

Ich bekomme die Ausnahme im Titel dieser Nachricht angezeigt, wenn ich versuche, auf eine Eigenschaft des Typs Int32 zuzugreifen - aber ich bekomme es auch für Nullable Typen und andere. Die Ausnahme wird ausgelöst, wenn ich versuche, den Ausdruck in die Funktion zu kompilieren.

Kann mir jemand vorschlagen, wie ich das anders machen könnte, während ich die Lambda-Funktionalität beibehalte, damit ich die Accessoren zwischenspeichern kann?

Antwort

94

Haben Sie versucht, Expression.Convert zu verwenden? Dadurch wird die Boxing/Lifting/etc-Konvertierung hinzugefügt.

Expression conversion = Expression.Convert(expression, typeof(object)); 
func = Expression.Lambda<Func<T, Object>>(conversion, parameterExpression).Compile(); 
+1

Sie waren sehr zufrieden mit dieser Antwort schließen, nur, es sei „Ausdruck“, die konvertiert werden musste und nicht „Parameterexpression“ (Ausdruck = Expression.Convert (Ausdruck, typeof (Object)); ) kurz vor dem Zusammenstellung. Danke. –

+1

Ups - danke, behoben. –

+0

Arbeitete Brillant! – Schotime

Verwandte Themen