给定两个泛型类型变量,如何编译system.linq.expression树以将它们相乘?如果表达式抛出异常,如果两种类型之间没有有效的运算符*,则完全可以接受。
我选择了System.Linq.Expression,因为我记得在这里看到过这种方式,但对于如何做到这一点还不够。
感谢。
编辑:我选择编译Linq表达式以获得速度;这应该尽可能快。
答案 0 :(得分:4)
您可以通过编写以下代码了解如何执行此操作:
Expression<Func<int, int, int>> multiply =
(left, right) => left * right;
将其编译成程序集并使用IL反汇编程序(如Reflector)查看C#编译器生成的代码。
使用给定的示例,C#编译器将生成如下内容:
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 });
这正是指定乘法表达式所需要做的。
当置于通用方法中时,它可能如下所示:
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();
}
答案 1 :(得分:2)
尝试这样的事情:
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);
如果类型T
没有有效的乘法运算符,Expression.Multiply
行将抛出异常。
答案 2 :(得分:2)
我选择了System.Linq.Expression
请注意:还有另一种简单方法:
public static T Multiply<T>(T x, T y) {
return ((dynamic)x) * y;
}
将工作(包括缓存)卸载到框架。另一个选项 - MiscUtil has generic operator support将其包装起来 - 可下载here。