繁体   English   中英

是否可以使用运行时变量设置Func <>函数,以忽略将它们作为C#中的参数传递?

[英]Can I set a Func<> function with runtime variables to omit passing them as parameters in C#?

我有一个数值分析程序,为简单起见,它会计算类似于以下内容的算法:

y = ax^3 + bx^2 + cx + d;

我在运行时计算a,b,c,d的值,并希望将以下等效形式传递为Func<double, double> 在这里我可以为X设置一个值,并得到Y。

y = 12x^3 + 13x^2 + 14x + 15; 

其中12,13,14,15是在运行时计算的数字。

我意识到这可以通过传递双Func<double[], double>数组来完成,如下所示: Func<double[], double>但我试图避免传递常量(可以是多个)。

有什么方法可以在运行时在func中设置这些数字吗?

(最好不计算Func <>本身的a,b,c,d部分?a,b,c,d的计算是功的80%)

例如:

a = ...

b = ...

c = ...

Func<x, double> {
     ((const)a) * x^3 +   ((const)b) * x^2 +   ((const)c) * x + 15;
}`

对于ABCD的每次评估-我将评估10 x。

我不确定我是否完全理解您的要求,但是您可以尝试这样的方法吗?

Func<double, double> CreateCalculationFunc()
{
    double a = heavy calculation;
    double b = heavy calculation;
    double c = heavy calculation;
    double d = heavy calculation;

    Func<double, double> calculation = (x) =>
    {
        // You can use the constants in here without passing them as parameters
        return x * (a * b / c - d);
    };

    return calculation;
}

在这种情况下,您只需调用CreateCalculationFunc() ,它将进行一次繁重的计算,然后返回可重用的Func<double,double>进行变量计算。

当然,这可以扩展到任意数量的预先计算的常数和多个变量。

您无法创建一个包含计算方法的类( Func<double,double> ),该方法具有“常量”的属性。 然后,设置属性并使用对Calculate方法的引用作为Func<double,double>委托:

public class Calculator
{
    public double A { get; set; };
    public double B { get; set; };
    public double C { get; set; };
    public double D { get; set; };

    public double Calculate(double x)
    {
        return A*x*x*x + B*x*x + C*x + D;
    }
}

这听起来像您想要功能语言所说的“ currying”或“ partial application”。

给定Func<a, b, c, d, x, result>您将一个一个地应用值并减少参数集。

Func<a, b, c, d, x, result>(valueOfA)

会导致带有签名的功能

Func<b, c, d, x, result>

你可以继续下去

C#中的currying / partial应用程序的相关链接:

或者-尝试F#;)

编辑:一个简短的代码示例,从上面的参考站点创建:

样板代码:

    public static Func<B, R> Partial<A, B, R>(this Func<A, B, R> f, A a) {
        return b => f(a, b);
    }

    public static Func<B, C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a) {
        return (b, c) => f(a, b, c);
    }

    public static Func<B, C, D, R> Partial<A, B, C, D, R>(this Func<A, B, C, D, R> f, A a) {
        return (b, c, d) => f(a, b, c, d);
    }

您的代码:

Func<double, double, double, double, double> yourCalculation = (a, b, c, x) => a*Math.Pow(x, 3) + b*Math.Pow(x, 2) + c*x;

var aDefined = yourCalculation.Partial(12);
var bDefined = aDefined.Partial(13);
var cDefined = bDefined.Partial(14);

cDefined现在是一个新的Func,它“知道”预先应用的值,并且可以根据需要传递。 我找不到具有超过4个参数(即,不适合Func <...>的参数)的委托人的现成解决方案,但这也应该可行。

这样,您就可以像现在一样进行一次和仅一次的预先计算,但是您可以将函数缩小到每个消费者的最后一部分。

有几种不同的Func <>重载,您可以将其与5个通用参数一起使用,第一个是KeyValuePair

Func<KeyValuePair<double,double>,double,double,double,double>

因此,您将a和b作为kvp传递,并将c,d和x作为其他参数传递。

事后看来,我实际上可以这样做。

Class {
    a = ...
    b = ...

    Func Algorithm = (x) => {
        return x*a + x*b;
    }

    return Algorithm;
}

但是对Func <>和Action <>有点困惑,因为这是我第一次使用它们! 谢谢你的帮助。

暂无
暂无

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

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