How can I sort-of "up-cast" where if I have an expression Expression.Constant(3)
and Expression.Constant(3d)
, it will up-convert the int to a double?
I know I can convert using Expression.Convert()
but what is the best way to determine which type can be implicitly up-cast?
I'm writing a simple equation evaluator, so the only expected input types are Value Types
The key thing to consider here is that System.Linq.Expressions
, which is used by both LINQ and the Dynamic Language Runtime, is designed to be a language-agnostic code model. The idea is to make it possible to create a "compiler" that can transform expressions from any arbitrary language into LINQ/DLR trees. Different languages have their own rules governing what kinds of conversions occur implicitly or explicitly, so the expression tree API and compiler tend to be very strict about requiring types to match up exactly. It is the job of the "compiler writer" (or whatever code is generating these expression trees) to explicitly inject whichever conversions are required to match the source language semantics.
The semantics of your custom expression language are up to you; you can choose to base them off an existing language like C#, but you will not find many facilities within the LINQ/DLR frameworks to tell you which kinds of conversions "should" happen implicitly, because there is no standard set of rules for this; such rules are language-dependent. Whatever rules you decide on, it will ultimately be up to you to inject the necessary conversions into your expression tree. This is a non-trivial task, and there is no "one size fits all" solution that one can simply post to StackOverflow.
On the upside, there is very little cost to having "unnecessary" Convert
expressions in your tree; if the bytecode-level conversion from one type to another is effectively a no-op, then no extra bytecode will be emitted when the expression is compiled.