【问题标题】:Multiply two lambda with Expression将两个 lambda 与表达式相乘
【发布时间】:2023-03-15 12:11:01
【问题描述】:

基本上,我试图将两个 lambda 表达式与类 Expression 相乘,但我什至无法构建,也找不到关于此的文档。这是我的代码:

var f = x=>x+2;
var g = x=>x+3;
var argX = Expression.Parameter(typeof(double), "x");
var fg = Expression.Multiply(Expression.Constant(g, typeof(Func<double, double>)), Expression.Constant(f, typeof(Func<double, double>)));
//var fg = Expression.Multiply(Expression.Constant(g),Expression.Constant(f));
var lambda = Expression.Lambda<Func<double, double>>(f3, argX);
return lambda.Compile();

【问题讨论】:

  • 两个函数相乘是什么意思?您可以乘以 ,但不能乘以 函数
  • 就像我说的,将两个 lambdas 相乘是没有意义的。我知道 lambda (可以)返回一个值。您可以将执行两个 lambda 的结果相乘(如果它们是委托),但这与将 lambda 本身相乘有很大不同。你不应该担心这样的事情的性能。首先让它工作,然后,如果你发现性能问题,看看你的代码在哪里花费了大量时间,并考虑如何改进它。我非常有信心你的代码会使用表达式来执行更糟糕的这样的东西。
  • 好的,但这不适用于“乘以 lambda”,而只是“创建一个 lambda,它是一个数字乘以另一个数字的结果”。所以我想fg 也需要是表达式。
  • @V.Leymarie 如果您关心性能,那么您几乎可以肯定想要使用表达式。它实际上肯定会使代码性能更差。如果您正在接受两个代表,那么您正在接受两个代表。这与问题高度相关。此外,如果您想创建一个新委托,表示使用其参数调用其他两个委托并将结果相乘,那么问这个而不是询问如何多个委托,因为您不乘以委托,您多个,(在这种情况下)由委托提供。
  • @V.Leymarie 最后,fg - Expression&lt;Func&lt;double, double&gt;&gt;Func&lt;double, double&gt; 的类型到底是什么?

标签: c# performance lambda linq-expressions


【解决方案1】:

你想要这样的东西吗:

Expression<Func<double,double>> f = x => x + 2;
Expression<Func<double,double>> g = x => x + 3;

var param = Expression.Parameter(typeof(double));
var invokeF = Expression.Invoke(f, param);
var invokeG = Expression.Invoke(g, param);

var mult = Expression.Multiply(invokeF,invokeG);

var lambda = ((Expression<Func<double, double>>)Expression.Lambda(mult, param)).Compile();

如果我这样称呼它:

lambda(3);

我得到 30 作为有效答案。

【讨论】:

  • 我会稍微改变一下 lambda 行以直接编译它:var lambda = (Func&lt;double, double&gt;) Expression.Lambda(mult, param).Compile(); 然后你可以跳过Compile() 调用,以便以后使用它。
【解决方案2】:

为此,只需将fg 也定义为Expression

var argX = Expression.Parameter(typeof(double), "x");

var f = Expression.Add(argX, Expression.Constant(3.0)); // applies to x => x + 3
var g = Expression.Add(argX, Expression.Constant(2.0)); // applies to x => x + 2
var fg = Expression.Multiply(f, g); // applies to f(x) * g(x)
var lambda = Expression.Lambda<Func<double, double>>(fg, argX);

现在这样称呼它:

var r = lambda.Compile()(1);

返回12

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多