这个C#函数组合方法是如何工作的?
How does this C# function composition method work?
我出现了以下代码:
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));
}
}
对我来说最大的谜是这个
return a => f2(f1(a));
你能解释一下它是如何工作的吗?
它将return一个Func<T1, T3>
,这是一个函数(委托),它接受一些T1
类型的参数和return一个结果类型 T3
。我们称 returned Func
f
f
的结果(returned值)只是2个函数参数f1
和f2
组合的结果(如数学函数组合)在给定的任何参数上。
有关 f
的更多信息,returned Func
:
对参数 a
(类型 T1
)应用 f1
,得到一些结果 b
(类型 T2
),然后应用 f2
在 b
上,将此结果称为 c
(类型 T3
)。 c
将是任何 a
传递给 f
的结果。
您需要了解高阶函数的概念才能理解上述方法。高阶函数在 .NET 中建模为 delegates,因此在 c# 中。委托是一种数据类型,表示要调用的方法。所以当你执行你的方法时,你得到的结果是你需要调用的另一个方法来获得你的结果(因此高阶函数)。
那么让我们来剖析一下你的方法:
参数Func<T1, T2> f1
和Func<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);
您可以像调用 f1
一样调用 f2
,只是使用不同的参数类型。由于T2
是f1
的return和T2
的参数,所以直接将f1
的结果传给f2
即可:
T2 result = f2(value);
或内联:
T2 result = f2(f1(a));
您会在您的方法中找到它,这意味着它执行两个方法的嵌套调用。
在一个特殊的转折中,Compose
不调用方法和 return 结果,它 return 本身是一个高阶函数。为此,它使用 lambda 运算符 =>
,这是创建委托的另一种方法。 lambda 运算符的左侧是 a
,它是新函数参数的任意名称。 a
的类型是T1
,编译器可以通过type inferrence.
推算出来
所以最后调用者必须执行 returned 委托才能得到最终结果。这称为 延迟执行,在 LINQ 中很常见。
您可以考虑使用 Compose
方法在实际调用之前嵌套调用两个方法。
我出现了以下代码:
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));
}
}
对我来说最大的谜是这个
return a => f2(f1(a));
你能解释一下它是如何工作的吗?
它将return一个Func<T1, T3>
,这是一个函数(委托),它接受一些T1
类型的参数和return一个结果类型 T3
。我们称 returned Func
f
f
的结果(returned值)只是2个函数参数f1
和f2
组合的结果(如数学函数组合)在给定的任何参数上。
有关 f
的更多信息,returned Func
:
对参数 a
(类型 T1
)应用 f1
,得到一些结果 b
(类型 T2
),然后应用 f2
在 b
上,将此结果称为 c
(类型 T3
)。 c
将是任何 a
传递给 f
的结果。
您需要了解高阶函数的概念才能理解上述方法。高阶函数在 .NET 中建模为 delegates,因此在 c# 中。委托是一种数据类型,表示要调用的方法。所以当你执行你的方法时,你得到的结果是你需要调用的另一个方法来获得你的结果(因此高阶函数)。
那么让我们来剖析一下你的方法:
参数Func<T1, T2> f1
和Func<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);
您可以像调用 f1
一样调用 f2
,只是使用不同的参数类型。由于T2
是f1
的return和T2
的参数,所以直接将f1
的结果传给f2
即可:
T2 result = f2(value);
或内联:
T2 result = f2(f1(a));
您会在您的方法中找到它,这意味着它执行两个方法的嵌套调用。
在一个特殊的转折中,Compose
不调用方法和 return 结果,它 return 本身是一个高阶函数。为此,它使用 lambda 运算符 =>
,这是创建委托的另一种方法。 lambda 运算符的左侧是 a
,它是新函数参数的任意名称。 a
的类型是T1
,编译器可以通过type inferrence.
所以最后调用者必须执行 returned 委托才能得到最终结果。这称为 延迟执行,在 LINQ 中很常见。
您可以考虑使用 Compose
方法在实际调用之前嵌套调用两个方法。