Suppose I have the following type with an implicit convertion operator:
public readonly struct WrappedInt
{
public WrappedInt(int value)
{
Value = value;
}
public int Value { get; }
public static implicit operator int (WrappedInt wrapper) => wrapper.Value;
}
Then here is an application:
var wrapper = new WrappedInt(42);
int x1 = Unwrap(wrapper);
int x2 = UnwrapUsingExpression(wrapper);
private static int Unwrap(WrappedInt wrapper)
{
int result = wrapper;
return result;
}
private static int UnwrapUsingExpression(WrappedInt wrapper)
{
var wrapperParameterExpression = Expression.Parameter(typeof(WrappedInt), "wrapper");
var resultVariableExpression = Expression.Variable(typeof(int), "result");
Expression right = wrapperParameterExpression; // THIS is important
var assignExpression = Expression.Assign(resultVariableExpression, right);
var blockExpression = Expression.Block(
new ParameterExpression[] { resultVariableExpression },
new Expression[] { resultVariableExpression, assignExpression, resultVariableExpression }
);
var unwrapFunc = Expression.Lambda<Func<WrappedInt, int>>(blockExpression, wrapperParameterExpression).Compile();
return unwrapFunc(wrapper);
}
Please note that in the Unwrap
function I do int result = wrapper;
which uses my implicit convertion operator - fine.
Now I want to do the same but in the expression tree - UnwrapWithExpression
routine. Here I'm assigning my 'result' variable directly to 'wrapper' parameter using
Expression right = wrapperParameterExpression;
But this does not work - I get a runtime exception:
System.ArgumentException: 'Expression of type 'WrappedInt' cannot be used for assignment to type 'System.Int32'.
I know how to work around it, basically either access the Value
property:
Expression right = Expression.Property(wrapperParameterExpression, nameof(WrappedInt.Value));
Or converting it:
Expression right = Expression.Convert(wrapperParameterExpression, typeof(int));
But why I cannot simply use the original direct assignment and make my implicit operator do the work?