这个C#函数组合方法如何工作?

时间:2017-10-13 08:02:30

标签: c# .net functional-programming func

我发现了以下代码:

public static class FuncUtils
{
    public static Func<T1, T3> Compose<T1, T2, T3> (Func<T1, T2> f1, Func<T2, T3> f2)
    {
        return a => f2(f1(a));
    }
}

对我而言最神秘的是这一个

  

返回a =&gt; F2(F1(A));

你能解释它是如何运作的吗?

2 个答案:

答案 0 :(得分:4)

它将返回Func<T1, T3>,它是一个函数(委托),它接受T1类型的某些参数并返回类型T3 的结果。让我们调用返回的Func f

f的结果(返回值)只是 2个函数参数f1f2组成的结果(如数学函数组合中所示)对任何参数给出。

f的更多内容,返回的Func

在参数f1(类型为a)上应用T1,获取一些结果b(类型为T2),然后应用{{1在f2上,调用此结果b(类型为c)。 T3将是传递给c的任何a的结果。

答案 1 :(得分:2)

您需要了解更高阶函数的概念才能理解上述方法。高阶函数在.NET中被建模为委托,因此在c#中。委托是表示要调用的方法的数据类型。因此,当您执行方法时,您获得的结果是您需要调用以获取结果的另一种方法(因此更高阶函数)。

让我们剖析你的方法:

参数Func<T1, T2> f1Func<T2, T3> f2是委托,每个都代表一种方法。您可以通过调用委托来调用这些方法:

//You need a value of type T1, here represented by the variable a
T2 value = f1(a);

调用必须如下所示,因为这是委托ID定义的方式:

public delegate TResult Func<T, TResult>(T item);

您可以像调用f2一样调用f1,只是使用不同的参数类型。由于T2f1的返回值和T2的参数,因此您只需将f1的结果传递给f2

T2 result = f2(value);

或内联:

T2 result = f2(f1(a));

您可以在方法中找到它,这意味着它会执行两种方法的嵌套调用。

在一个特殊的转折中,Compose不会调用方法并返回结果,它会自动返回一个更高阶的函数。它使用lambda运算符=>,这是另一种创建委托的方法。 lambda运算符的左侧是a,它是新函数参数的任意名称。 a的类型是T1,编译器可以通过类型推理找出它。

所以最后调用者必须执行返回的委托才能获得最终结果。这称为 deferred execution ,在LINQ中很常见。

在实际进行调用之前,您可以考虑使用Compose方法将调用嵌套到两个方法中。