【问题标题】:ParameterExpression of type 'System.Int32' cannot be used for delegate parameter of type 'System.String'“System.Int32”类型的 ParameterExpression 不能用于“System.String”类型的委托参数
【发布时间】:2012-03-29 14:37:32
【问题描述】:

我正在使用表达式树创建一个通用设置器,这是我的代码

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 创建操作而没有任何错误,而为Age 它会爆炸。

Age 的这一行发生错误:

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

错误:

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

我可以用动态..做点什么吗?

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

【问题讨论】:

  • 为什么不将年龄转换为 int,然后再将其传递给操作?

标签: c# generics dynamic delegates expression-trees


【解决方案1】:

你应该调用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&lt;Action&lt;T,string&gt;&gt;,这基本上意味着结果将是一个string。另一方面,您传入“Age”作为操作应返回的字段名称。 Ageint 类型,而不是 string

    您至少可以通过两种方式解决此问题:

    1. 向您的GetAction 方法添加第二个泛型参数,用于指定返回类型。
    2. 在表达式的返回属性上添加对ToString 的调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多