ParameterExpression of type 'System.Int32' cannot be used for delegation parameter of type 'System.String'

I am creating a generic setter using an expression tree and here is my code

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

      

I do not name .Compile()

in the above method because I want to examine the expression it expressed.

And my object

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

}

      

I am calling a method like this

var lastname = GetAction<Person>("FirstName");
var age = GetAction<Person>("Age");

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

      

The reason I am passing age as a string is, I am getting this value from XML.

It creates Action for FirstName

no error, whereas for Age

it hits.

The error is on this line for Age

:

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

      

Mistake:

ParameterExpression of type 'System.Int32' cannot be used for delegation parameter of type 'System.String'

Is there anything you can do with dynamic ..?

I hope someone has some solution. thank

+3


source to share


2 answers


You should call Convert.ChangeType

for type conversion:



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

      

+3


source


The problem is this:

You are returning Expression<Action<T,string>>

, which basically means what the result will be string

. On the other hand, you go to Age as the field name, the action should return. Age

however is of type int

and not string

.



You can solve this in at least two ways:

  • Add a second generic parameter to your method GetAction

    that specifies the return type.
  • Add a call ToString

    to the return property to the expression.
+2


source







All Articles