Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception when generating Expression.Assign to set decimal? from decimal

I ran into an interesting issue when building Expressions. I had some basic type coercion checks going to ensure minimal casting was done, however, I ran into an issue I didn't expect.

When I am trying to generate a BinaryExpression using Expression.Assign and I am going from decimal to decimal? I receive the exception:

System.ArgumentException: 'Expression of type 'System.Decimal' cannot be used for assignment to type 'System.Nullable'1[System.Decimal]

Can someone explain this? Considering the following evaluates to true:

typeof(decimal?).IsAssignableFrom(typeof(decimal))

The expected assignment should be equal to the statements below:

decimal? x = null;
decimal y = 10;
x = y;

Code in question:

private Expression BuildMapExpressionForValueMap(MemberInfo destinationProperty, MemberInfo sourceProperty)
{
    Expression assignmentExpression = Expression.PropertyOrField(_source, sourceProperty.Name);
    Type destinationType = destinationProperty.GetUnderlyingType();

    if (!destinationType.IsAssignableFrom(sourceProperty.GetUnderlyingType()))
    {
        assignmentExpression = BuildCastExpression(assignmentExpression, destinationType);
    }

    var expression = Expression.Assign(Expression.PropertyOrField(_destination, destinationProperty.Name)
                                     , assignmentExpression);


    return expression;
}
like image 642
Samir Banjanovic Avatar asked Nov 01 '25 08:11

Samir Banjanovic


1 Answers

There are implicit conversions from the non-nullable value types to the corresponding nullable type. The expressions you generate must be explicit. The same reason why you can't generate an expression assigning an Int32 to a variable of type Int64. The compiler generates the conversion calls explicitly so you don't have to. Try it and you'll see.

You must add the conversion.

var param = Expression.Variable(typeof(decimal?));
var value = Expression.Constant(20m, typeof(decimal));
var expr = Expression.Assign(param,
    //value // fails
    Expression.Convert(value, param.Type)
);
like image 73
Jeff Mercado Avatar answered Nov 02 '25 22:11

Jeff Mercado



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!