文本区域对于具有反射的可为空类型

本文关键字:类型 反射的 区域 于具 文本 | 更新日期: 2023-09-27 17:56:32

    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;
    }

这是我的调用函数

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);
    }

下面是一个示例类:

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

我采用了 GetValue 来自:成员表达式无法从可为空的十进制转换为对象这似乎工作得很好,直到您到达不属于对象类型的属性,我收到此错误:

类型为"System.Nullable"1[System.Int32]"的参数表达式不能用于类型为"Test"的委托参数

真的不确定我在这里哪里出错了,以及这个错误甚至意味着什么

文本区域对于具有反射的可为空类型

如果我理解正确,您需要属性访问 lambda。以下是GetValue<T>方法的正确版本:

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);  
}

如果您想通过提供委托(在您的问题中是Func<T,..>)来Expression,那么您还必须提供委托类型、正文表达式和参数表达式:

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"));        
}