C# 解释此代码

C# 解释此代码,c#,lambda,C#,Lambda,请解释此代码: public static Func<TInput1, TOutput> Curry<TInput1, TOutput>(this Func<TInput1, TOutput> f) { return x => f(x); } 公共静态函数(此函数) { 返回x=>f(x); } 或 Func SubtractOne=x=>x-1; 这些技术的名称是什么 这是一种新的语言特性,称为 var result = Subtract

请解释此代码:

public static Func<TInput1, TOutput> Curry<TInput1, TOutput>(this Func<TInput1, TOutput> f)
{
    return x => f(x);
}
公共静态函数(此函数)
{
返回x=>f(x);
}

Func SubtractOne=x=>x-1;

这些技术的名称是什么

这是一种新的语言特性,称为

var result = SubtractOne(5);
Assert.AreEqual(4, result);
第二个函数生成一个函数,该函数接受名为
x
Int32
并返回一个等于
x-1
Int32
,然后将该函数分配给名为
Func
的委托类型的变量

它相当于以下C#1.0代码:

delegate int MyFunc(int x);
static int SubtractOneFunction(int x) { return x - 1; }

MyFunc SubtractOne = new MyFunc(SubtractOneFunction);

第一个示例实际上是一个no op,因为输入函数已经是curried形式;它只是给调用增加了一个额外的间接层次。如果你对咖喱感兴趣,那就先看看


第二个示例创建了一个名为
SubtractOne
,它将从所传递的参数中减去一个。

第一个代码段只有在伴随几个类似的重载时才有意义。可能只是为了完成一组名为
Curry
的方法。这个词来源于名称,指的是编程语言(或库)向函数提供所需参数子集的能力,以便获得另一个接受其余函数的函数。举个例子更容易理解:

void Foo(int a, string b, bool c) { ... }
您可以通过提供所有三个参数将其称为:

Foo(123, "hi", false);
但在咖喱中,你可以做到:

var foo123 = Foo(123);
它将返回另一个函数,该函数接受其余两个参数,因此我们说它将第一个参数“绑定”到值123。但是,如果你可以使用原来的函数,你也可以使用新函数:

var foo123Hi = foo123("hi");
最后提供最后一个论点:

foo123Hi(false);
最后我们有了所有三个参数,直到现在,
Foo
的定义才真正执行

在许多函数式语言中(毫不奇怪在Haskell和Curry语言中),这是内置在语言中的。在C#中不是,尽管您可以通过提供一组重载来部分模拟它,例如:

Action<string, bool> Foo(int a)
{
    return (b, c) => Foo(a, b, c);
}

Action<bool> Foo(int a, string b)
{
    return c => Foo(a, b, c);
}
动作Foo(inta) { 返回(b,c)=>Foo(a,b,c); } 动作Foo(int a,string b) { 返回c=>Foo(a,b,c); } 但这仍然不太正确,因为在第一个示例中,返回的
操作
不能直接使用

因此,有时会有人试图提供一个可以在任何函数上进行curry的curry库


但对于一个足够简单的lambda语法,实际上并不清楚任何库解决方案是否会有那么大的帮助。毕竟,lambda是绑定一个参数的非常简单的方法,如上面的示例所示。所以我不确定“Curry”方法库会被广泛使用。
=>
操作符更清晰、更不笨重、功能更强大、可读性更强,并且已经内置。

第二个是函数式编程。。现在记不起名称了。问题到底是什么?这项技术的名称是什么?第一项命名错误@SLaks——事实上,它应该被命名为
NoOp
!那么,在这种情况下,它相当于。。。但不是在一般情况下,因为lambda表达式(和C#2.0匿名委托)可以捕获局部变量,这在C#1.0+1中是不可能的。谢谢您的示例。
Action<string, bool> Foo(int a)
{
    return (b, c) => Foo(a, b, c);
}

Action<bool> Foo(int a, string b)
{
    return c => Foo(a, b, c);
}