Pet*_*son 22 .net c# generics arguments functional-programming
由于Javascript是我最熟练的语言,因此我熟悉将函数用作第一类对象.我原以为C#缺少这一功能,但后来我听说Func和Action和delegate,我认为这是相当awesomesauce.
例如,您可以声明一个Func连接两个字符串并在它们之间放置一个空格,如下所示:
Func<string, string, string> concat = (a,b) => a + " " + b;
Run Code Online (Sandbox Code Playgroud)
当你输入时我注意到了
Func<
Run Code Online (Sandbox Code Playgroud)
IntelliSense显示它有17个重载:
delegate System.Func<out TResult>
delegate System.Func<in T, out TResult>
delegate System.Func<in T1, in T2, out TResult>
...snip...
delegate System.Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult>
Run Code Online (Sandbox Code Playgroud)
那让我开怀大笑.我看了看MSDN文档的Func又一次笑了起来.这让我尝试Func用17个参数声明一个.它会导致错误(Using the generic type 'System.Func<TResult>' requires 1 type arguments).
我同意,拥有一个Func接受超过16个参数的东西可能不是一个好主意.即便如此,这似乎是一种可行的方式Func.它需要记录17个简单的不同重载.这是它真正需要知道的全部内容:最后一个类型参数是返回类型,并且它之前的所有类型参数都是参数类型.
那么,如果我想创建一个Func超过16个参数,我该怎么办?为什么还有限制?为什么C#不能让你Func用任意数量的参数声明一个?
Eni*_*ity 15
您只需定义所需的任何委托即可.所以Func有20个参数定义如下:
public delegate R Func<
P0, P1, P2, P3, P4, P5, P6, P7, P8, P9,
P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, R>(
P0 p0, P1 p1, P2 p2, P3 p3, P4 p4,
P5 p5, P6 p6, P7 p7, P8 p8, P9 p9,
P10 p10, P11 p11, P12 p12, P13 p13, P14 p14,
P15 p15, P16 p16, P17 p17, P18 p18, P19 p19);
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
Func<
int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int, int, int> f = (
p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
p11, p12, p13, p14, p15, p16, p17, p18, p19) =>
p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10
+ p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19;
var r = f(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
Run Code Online (Sandbox Code Playgroud)
C#还允许您在任何委托上使用lambda语法,因此您也可以这样做:
public delegate R ArrayFunc<P, R>(params P[] parameters);
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
ArrayFunc<int, int> af = ps => ps.Sum();
var ar = af(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
Run Code Online (Sandbox Code Playgroud)
它是该语言非常灵活和强大的功能.
我想我明白了 - 你可以用JavaScript和函数(参数)做些什么是整洁而且它也不是静态类型的.
但请注意,无论如何,您在函数式编程中绝不需要多个参数.您可以通过返回另一个函数来链接尽可能多的参数(这是FP中的常见特性,并且通常用于限制JS中可用的技术,但只是稍微弯曲系统).
当然这在C#中很尴尬:
Func<A1,Func<A2,Func<A3,...<Func<An,Result>>...>
x1 =>
(x2 =>
(x3 =>
...
(xn =>
{ /*return soomething */ }
))...);
Run Code Online (Sandbox Code Playgroud)
但这就是F#的用途;)当然,你永远不应该使用多个参数(低于16的方式!)来创建一个函数.