2010-02-04 12 views
49

Próbuję utworzyć prosty system skryptów, który będzie używany do drukowania etykiet. Zrobiłem to w przeszłości z refleksją bez problemu, ale teraz próbuję to zrobić z funkcjami Lambda, aby móc buforować funkcje do ponownego użycia.Wyrażenie typu "System.Int32" nie może być używane do zwracania typu "System.Object"

Kod mam tak daleko jest następujący ...

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; 

    } 

} 

To wydaje się działać w niektórych przypadkach, ale w innych nie. Problem polega na tym, że próbuję zwrócić wartości jako obiekty - niezależnie od rzeczywistych typów danych. Próbuję to zrobić, ponieważ nie wiem, w czasie kompilacji, jaki będzie typ danych, ale w dłuższej perspektywie, potrzebuję tylko ciąg.

Otrzymuję wyjątek wskazany w tytule tego komunikatu za każdym razem, gdy próbuję uzyskać dostęp do właściwości typu Int32 - ale otrzymuję ją także dla typów zerowalnych i innych. Wyjątek jest zgłaszany, gdy próbuję skompilować wyrażenie do funkcji.

Czy ktoś może zasugerować, w jaki sposób mogę inaczej postępować, zachowując funkcjonalność Lambda, aby móc buforować akcesory?

Odpowiedz

94

Czy próbowałeś używać Expression.Convert? To doda konwersję boksu/podnoszenia/etc.

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

Byliście bardzo blisko z tej odpowiedzi, tylko że to „ekspresja”, które musiały być przekształcane, a nie „parameterExpression” (wyrażenie = Expression.Convert (wyrażenie, typeof (Object)); ) tuż przed kompilacja. Dzięki. –

+1

Ups - dzięki, naprawione. –

+0

Pracował doskonale! – Schotime

Powiązane problemy