1

给定两个泛型类型变量,如何编译 system.linq.expression 树以将它们相乘?如果两种类型之间没有有效的运算符 *,则表达式抛出异常是完全可以接受的。

我选择 System.Linq.Expression 是因为我记得在这里看到它是这样做的,但关于如何做的还不够。

谢谢。

编辑:我选择编译 Linq 表达式以提高速度;这应该尽可能快。

4

3 回答 3

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();
}
于 2012-10-30T20:00:08.700 回答
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);

如果 type 没有有效的乘法运算符T,则该Expression.Multiply行将引发异常。

于 2012-10-30T19:59:57.997 回答
2

我选择了 System.Linq.Expression

只是要清楚:还有另一种简单的方法:

public static T Multiply<T>(T x, T y) {
    return ((dynamic)x) * y;
}

并将工作(包括缓存)卸载到框架。另一种选择 - MiscUtil 具有通用的操作员支持,将其包装起来 - 可在此处下载。

于 2012-10-30T20:06:03.850 回答