推断具有function组合的generics类型

假设我想实现一个function组合,如下所示:

public Func Compose(Func f, Func g) { return new Func( x => f(g(x))); } 

现在在实践中,我可以像这样使用这个Compose()fn:

  public String ToUpper(String s) { return s.ToUpper(); } public String Replicate(String s) { return s+s; } public void Run() { var h = Compose(ToUpper, Replicate); System.Console.WriteLine("{0}", h("fred")); } 

结果是FREDFRED

有没有办法使用更简单的语法来调用Compose? 我试过这样的:

  var h = Compose(ToUpper, Replicate); 

…但我收到编译错误:

错误CS0411:无法从用法推断出方法’FunctionalTest.Compose(System.Func,System.Func)’的类型参数。 尝试显式指定类型参数。

很容易理解。 我想知道是否有可能以不同的方式声明它并得到实际工作的推断。


编辑
问题的根源:我正在观看本科生function编程课程的在线讲座,UC Berkley的CS61A。 (在youtube上找到它)。 我没有关于FP的正式培训,我想我可能会学到一些东西。 教授使用方案,他谈到方案+ lisp是纯函数式语言,而其他语言则不那么简单。 他特别指出Pascal,C,C ++和Java(但不是C#)缺乏function,并表示用这些语言进行function组合很难(“没有站在你的头上”)。 他声称指向函数的指针(在C,C ++中可用)与函数“entity”(lambda)不同。 我明白了。

好笑 – 他没有提到Javascript或C#,我认为它们是主流语言,两者都具有相当不错的function。 (我不知道F#。)

我觉得很奇怪这是去年 – 14个月前的讲座 – 然而他似乎并没有意识到主流现代语言的function方面。

所以我跟着做练习,但不是使用scheme或lisp,而是使用C#。 并且还在Javascript中执行其中一些操作。

无论如何,感谢大家对质量的反应。

以下代码可以工作:

 Func toUpper = ToUpper; Func replicate = Replicate; // now the compiler knows that the parameters are Func var h = Compose(toUpper, replicate); 

所以也许您仍然可以通过仅定义这些变量一次来获得您正在寻求的可读性改进,并且它们在整个测试中重复使用它们(我假设这是一个测试实用程序…)

我喜欢Ran的答案(+1),但我认为这会让它更简洁和美观。 (假设您可以按以下方式重新定义函数,则可以工作。)

 Func toUpper = s => s.ToUpper(); Func replicate = s => s + s; var h = Compose(toUpper, replicate); 

添加到lasseespeholt的答案,如果您将Compose定义为扩展方法(重命名为“Then”,以便结果更有意义):

 public static Func Then(this Func f, Func g) { return x => g(f(x)); } 

你可以说这个流利:

 var h = toUpper.Then(replicate); // .Then(trim) etc... 

您也可以传递Compose参数,并让它实际评估函数; 它应该能够推断出那种情况下的参数类型。 (但您可能仍需要指定返回类型。)

除此之外,不,没有办法在C#中推断出这样的事情。