0
votes
    public Expression GetValue<T>(T source, PropertyInfo property)
    {
            ParameterExpression fieldName = Expression.Parameter(pi.PropertyType, pi.Name);
            Expression fieldExpr = Expression.PropertyOrField(Expression.Constant(source), pi.Name);
            var exp = Expression.Lambda(typeof(Func<,>).MakeGenericType(typeof(T), fieldExpr.Type),
                    fieldExpr,
                    fieldName);
            return exp;

    }

Here is my calling function

public MvcHtmlString RenderModel(T model)
{
    foreach (var prop in typeof(T).GetProperties())
    {
         var x = InputExtensions.TextBoxFor(h, (dynamic) GetValue<T>(model, prop));
    }

    return new MvcHtmlString(string.Empty);
    }

Here is an example class:

public class Test
{
    public int? ID { get; set; }
    public string Name { get; set; }
    public DateTime? Date{ get; set; }
}

I adopted GetValue from part of: Member Expression cannot convert to object from nullable decimal which seems to work quite well until you reach properties that are not of type object I get this error:

ParameterExpression of type 'System.Nullable`1[System.Int32]' cannot be used for delegate parameter of type 'Test'

I'm not really sure where I've gone wrong here, and what that error even means

1

1 Answers

0
votes

If I understand correctly, you need property access lambda. Here is the correct version of GetValue<T> method:

public Expression GetValue<T>(T source, PropertyInfo pi)
{ 
    var param = Expression.Parameter(typeof(T), "p");
    Expression body = param;
    body = Expression.PropertyOrField(body, pi.Name);
    return Expression.Lambda(body, param);  
}

If you want to make an Expression by providing a delegate (that in your question it is Func<T,..> ) then you have to provide the delegate type, body expression and parameter expressions too:

public Expression GetValue<T>(T source, PropertyInfo property)
{
   return Expression.Lambda(
          delegateType: typeof(Func<,>).MakeGenericType(typeof(T), pi.PropertyType),
          body: Expression.PropertyOrField(Expression.Parameter(typeof(T), "x"), pi.Name),
          parameters: Expression.Parameter(typeof(T), "x"));        
}