I am trying to create a simple scripting system that will be used to print labels. I have done this in the past with reflection without problems, but now I am trying to do this using Lambda functions so that I can cache functions for reuse.
The code I have so far is as follows:
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; } }
In some cases this works, but in others it fails. The problem seems to be in my attempt to return values as objects - regardless of the actual data types. I try to do this because at compile time I do not know what data type will be, but in the end, I only need a string.
I get the exception indicated in the header of this post whenever I try to access a property of type Int32, but I also get it for types Nullable and others. An exception occurs when I try to compile an expression in a function.
Can anyone suggest how I can do this differently while supporting Lambda functionality so that I can cache accessors?
Martin Robins Feb 04 '10 at 14:10 2010-02-04 14:10
source share