That To
code seems to be you trying to construct a Constant
of nullable type when given a value of non-nullable type but that is not at all the right way to go about this. The way you're trying to do this indicates that you have a misunderstanding about how boxed value types work.
That error message indicates that you are constructing a binary operator expression tree node which has as its operands an expression node of nullable int type and an expression node of int type. That's not legal; they have to be both nullable int. What you should be doing is wrapping the non-nullable int expression tree node in a Convert
expression tree node which converts it to a nullable int, and then pass that to the binary operator expression tree node constructor.
That is, this is wrong:
var someIntExpr = Expression.Constant(123, typeof(int));
var someNubIntExpr = Expression.Constant(null, typeof(int?));
var badEq = Expression.Equal(someIntExpr, someNubIntExpr);
This is right:
var goodEq = Expression.Equal(Expression.Convert(someIntExpr, typeof(int?)), someNubIntExpr);
So why is what you're doing wrong?
You have a method To<T>
which returns a T
. It correctly takes in an int
and returns the equivalent int?
. So then what? You pass that to Expression.Constant
, which boxes the nullable int into a boxed int, and then makes a constant out of that. You believe that there is such a thing as a boxed nullable value type, but there is not! A nullable value type boxes either to a null reference or to a boxed non-nullable value type.
So you could also solve your problem by not doing any of this crazy stuff in the first place. If you have a boxed int in hand, and you need a constant expression tree node of nullable type, just provide the type.
Expression.Constant(someBoxedIntValue, typeof(int?))
Done. So: wrapping up, you have two solutions:
- If you have a boxed int in hand, pass it and the nullable value type you want to the
Constant
factory, or
- if you have an expression node of type int in hand then use the
Convert
expression node factory, and pass it and the desired type to that.
Both will give you back an expression node of the correct type to be compared to another nullable int.