简体   繁体   English

给定两个通用类型变量,如何编译system.linq.expression树以将它们相乘?

[英]Given two generic type variables, how do I compile a system.linq.expression tree to multiply them?

Given two generic type variables, how do I compile a system.linq.expression tree to multiply them? 给定两个通用类型变量,如何编译system.linq.expression树以将它们相乘? 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. 我之所以选择System.Linq.Expression,是因为我记得在这里看到过这种方式,但是还不够。

Thanks. 谢谢。

Edit: I chose compiling a Linq expression for speed; 编辑:我选择编译一个Linq表达式以提高速度; 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. 将其编译为一个程序集,并使用IL反汇编程序(例如Reflector)查看C#编译器生成的代码。

With the given example, the C# compiler will generate something like this: 对于给定的示例,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 });

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. 如果类型T没有有效的乘法运算符,则Expression.Multiply行将引发异常。

I chose System.Linq.Expression 我选择了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 . 另一种选择- MiscUtil具有普通运营商的支持 ,它包装这件事-下载这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM