类型为'System.Int32'的ParameterExpression不能用于类型为'System.String'的委托参数。

5
我正在使用表达式树创建一个通用的setter,这是我的代码:
public Expression<Action<T,string>> GetAction<T>(string fieldName)
{
    ParameterExpression targetExpr = Expression.Parameter(typeof(T), "Target");  
    MemberExpression fieldExpr = Expression.Property(targetExpr, fieldName);    
    ParameterExpression valueExpr = Expression.Parameter(fieldExpr.Type, "value"); 
    UnaryExpression valueCast = (!fieldExpr.Type.IsValueType) 
                              ? Expression.TypeAs(valueExpr, fieldExpr.Type) 
                              : Expression.Convert(valueExpr, fieldExpr.Type);
    BinaryExpression assignExpr = Expression.Assign(fieldExpr, valueCast);    
    return Expression.Lambda<Action<T, string>>(assignExpr, targetExpr, valueExpr);
}

我在上述方法中没有调用.Compile(),因为我想查看它构建的表达式。

我的目的是

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

}

我这样调用该方法。
var lastname = GetAction<Person>("FirstName");
var age = GetAction<Person>("Age");

lastname.Compile()(p, "Solutions");
age.Compile()(p, "10");

我之所以将年龄作为字符串传递,是因为我将从XML中获取此值。

它可以创建FirstName的Action而不会出现任何错误,但是对于Age则会出错。

错误发生在这行代码中Age

 return Expression.Lambda<Action<T, string>>(assignExpr, targetExpr, valueExpr);

错误:

类型为'System.Int32'的ParameterExpression不能用于类型为'System.String'的委托参数

我能通过dynamic做些什么..?

我希望有人能提供一些解决方案。谢谢


1
为什么你不在传递参数之前将年龄转换为整数类型呢? - M.Babcock
2个回答

6
您应该调用 Convert.ChangeType 进行类型转换:
public static Expression<Action<T, string>> GetAction<T>(string fieldName)
{
    ParameterExpression targetExpr = Expression.Parameter(typeof(T), "Target");
    MemberExpression fieldExpr = Expression.Property(targetExpr, fieldName);
    ParameterExpression valueExpr = Expression.Parameter(typeof(string), "value");
    MethodCallExpression convertExpr = Expression.Call(typeof(Convert),
        "ChangeType", null, valueExpr, Expression.Constant(fieldExpr.Type));
    UnaryExpression valueCast = Expression.Convert(convertExpr, fieldExpr.Type);
    BinaryExpression assignExpr = Expression.Assign(fieldExpr, valueCast);
    return Expression.Lambda<Action<T, string>>(assignExpr, targetExpr, valueExpr);
}

2
问题如下:
您正在返回一个Expression<Action<T,string>>,这基本上意味着结果将是一个string。另一方面,您正在将“Age”作为操作应返回的字段名称传递。然而,Ageint类型,而不是string
您可以通过以下至少两种方式解决此问题:
  1. GetAction方法中添加第二个泛型参数来指定返回类型。
  2. 对表达式中返回的属性调用ToString方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接