【发布时间】:2018-11-11 08:34:52
【问题描述】:
我最近一直在研究函数式编程,并希望将一些概念带入我的C# 世界。我正在尝试编写函数来创建服务(或任何你称之为的服务),而不是创建具有可注入依赖项的类。
我想出了一种方法,通过创建这样的静态方法来部分应用具有两个参数和一个返回参数的函数(与注入依赖项具有相同的效果):
// this makes a func with a single arg from a func with two
static Func<T2, TResult> PartiallyApply<T1, T2, TResult>(
Func<T1,T2, TResult> f,
T1 t1)
{
// use given t1 argument to create a new function
Func<T2, TResult> map = t2 => f(t1, t2);
return map;
}
这行得通,但是我想给它传递一个静态方法,比如这个:
static string MakeName(string a, string b) => a + " " + b;
当我尝试将其连接起来时,我收到错误 The type arguments for method 'Program.PartiallyApply<T1, T2, TResult>(Func<T1, T2, TResult>, T1)' cannot be inferred from the usage. 但是当我添加一个创建显式 Func<string,string,string 的步骤时,我指出它确实有效的方法:
static void Main(string[] args)
{
var first = "John";
var last = "Doe";
var f1 = PartiallyApply(MakeName, first); // cannot be inferred from the usage
Func<string, string, string> make = MakeName; // map it to func
var f2 = PartiallyApply(make, first); // works
var name = f2(last);
Console.WriteLine(name);
Console.ReadKey();
}
为什么直接传递静态方法时编译器无法计算出类型args?有没有一种方法可以使用静态方法,而无需显式地将它们映射到具有基本相同(类型)参数的Func<>?
更新
阅读Enrico Buonanno 的Functional programming in C#(强烈推荐)为解决这个问题提供了另一个不错的选择。在7.1.3 中,他提供了几个关于如何直接使用Funcs 而不是方法组的选项。
您可以使用 Func 像这样创建一个 getter only 属性:
static Func<string, string, string> MakeName => (a,b) => a + " " + b;
【问题讨论】:
-
静态部分似乎无关紧要。非静态和局部函数的行为也相同。
-
在调用 PartiallyApply 时指定通用参数的替代方法: var f1 = PartiallyApply((Func
)MakeName, first); -
我建议curry
MakeName本身(假设是你自己维护):static Func<string, Func<string, string> MakeName = a => b => a + " " + b;推荐阅读:codeblog.jonskeet.uk/2012/01/30/…
标签: c# functional-programming func partial-application