返回 Func的函数解释器

本文关键字:double 函数 解释器 Func 返回 | 更新日期: 2023-09-27 18:22:37

我正在使用数学函数解释器 Jace.NET。下面是如何使用它的一个很好的例子:

CalculationEngine engine = new CalculationEngine();
Func<double, double, double> formula = (Func<double, double, double>)engine.Function("x1+2/(3*x2)")
.Parameter("x1", DataType.FloatingPoint)
.Parameter("x2", DataType.FloatingPoint)
.Result(DataType.FloatingPoint)
.Build();

但是另一个库(我必须使用(需要Func<double[],double>作为输入,而不是 Jace 可以返回的Func<double,double,double>Func<double,double,double,double>

所以我需要一个解释器,它可以创建一个函数,该函数将双精度数组作为输入并返回一个值,所以基本上是这样的:

Func<double[],double> formula = ...

我试图在Jace中做到这一点,但没有运气。有什么想法吗?

返回 Func<double[],double>的函数解释器

lambda 表达式的优点之一是它们非常易于使用来创建委托实例,并且可以执行与常规方法完全相同的参数映射。

例如,如果你有一个需要调用的 API 并传递一个 Func<double[], double> ,但你手头实际上有一个Func<double, double, double>(例如(,你可以使用特殊类中的命名方法来做到这一点:

class FuncMapper
{
    private readonly Func<double, double, double> _func;
    public FuncMapper(Func<double, double, double> func)
    {
        _func = func;
    }
    public double M(double[] input)
    {
        return _func(input[0], input[1]);
    }
}

用于:

Func<double[], double> formula = new FuncMapper(jaceFunc).M;

但这相当冗长。使用 lambda 表达式,您可以让编译器完成大部分工作:

Func<double[], double> formula = array => jaceFunc(array[0], array[1]);

请注意变量捕获是否以及如何发生。lambda 表达式将根据其范围捕获jaceFunc;如果它是局部的并且在 lambda 表达式之后保持不变,那么它在 lambda 表达式中也将保持不变。但是,如果您捕获具有更宽生存期的变量,并且在调用 lambda 的委托之前对其进行了修改,则 lambda 表达式将使用变量的修改值。捕获的是变量,而不是其值。


笔记:

  • 您的特定场景涉及动态创建的委托(例如 jaceFunc上面(,但当然同样的事情也适用于命名方法。
  • 上面只显示了单个场景,即两个输入参数,而您说您可能有两个以上的输入参数。您可以根据需要解决此问题(即通过使用switch或类似方法(,也可以编写一个Expression构建方法,该方法基本上执行上述操作,但会考虑被调用方法的参数数量并生成必要的数组元素查找并将它们传递给调用的委托或方法。

    对于少数情况,switch要容易得多,但如果您需要概括不同的参数类型和方法签名变体,从长远来看,基于Expression的方法可能更有用。