Given two generic type variables, how do I compile a system.linq.expression tree to multiply them? It's perfectly acceptable if the expression throws an exception if the two types do not have a valid operator * between them.
I chose System.Linq.Expression because I recall seeing it done that way on here, but not enough about how.
Thanks.
Edit: I chose compiling a Linq expression for speed; this should be as fast as reasonably possible.
You can find out how to do this by writing the following code:
Expression<Func<int, int, int>> multiply =
(left, right) => left * right;
Compiling it down to an assembly and use a IL deassembler (such as Reflector) to look at the code the C# compiler produced.
With the given example, the C# compiler will generate something like this:
var left = Expression.Parameter(typeof(int), "left");
var right = Expression.Parameter(typeof(int), "right");
var multiply = Expression.Lambda<Func<int, int, int>>(
Expression.Multiply(left, right),
new ParameterExpression[] { left, right });
And this is exactly what you need to do to specify a multiply expression.
When placed in a generic method, it might look something like this:
public static Func<T, T, T> BuildMultiplier<T>()
{
var left = Expression.Parameter(typeof(T), "left");
var right = Expression.Parameter(typeof(T), "right");
var multiply = Expression.Lambda<Func<T, T, T>>(
Expression.Multiply(left, right),
new ParameterExpression[] { left, right });
return multiply.Compile();
}
Try something like this:
var left = Expression.Parameter(typeof(T), "left");
var right = Expression.Parameter(typeof(T), "right");
var body = Expression.Multiply(left, right);
return Expression.Lambda<Func<T, T, TResult>>(body, left, right);
If there is no valid multiplication operator for type T
, the Expression.Multiply
line will throw an exception.
I chose System.Linq.Expression
Just to be clear: there's another easy way:
public static T Multiply<T>(T x, T y) {
return ((dynamic)x) * y;
}
and offload the work (including cache) to the framework. Another option - MiscUtil has generic operator support that wraps this up - downloadable here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.