在 C# 中,我们执行以下操作:
class Program {
static Action Curry<T>(Action<T> action, T parameter) {
return () => action(parameter);
}
static void Foo(int i) {
Console.WriteLine("Value: {0}", i);
}
static void Main(string[] args) {
Action curried = Curry(Foo, 5);
curried();
}
}
显然,该方法Foo
对应于您的方法Foo
,只是使用适当的调用来Console.WriteLine
代替std::cout
。
接下来,我们声明一个Curry
接受一个Action<T>
并返回一个的方法Action
。一般来说,anAction<T>
是一个接受单个类型参数T
并返回的委托void
。特别是,Foo
是一个,Action<int>
因为它接受一个类型的参数int
并返回void
。至于 的返回类型Curry
,则声明为Action
。AnAction
是一个没有参数并返回的委托void
。
的定义Curry
相当有趣。我们正在使用 lambda 表达式定义一个动作,它是匿名委托的一种非常特殊的形式。有效
() => action(parameter)
表示void
参数映射到action
在 处求值parameter
。
最后,在Main
我们声明一个Action
名为的实例,curried
它是应用参数Curry
的结果。这与您的 C++ 示例中的作用相同。Foo
5
bind(fun_ptr(foo), 5)
curried
最后,我们通过语法调用新形成的委托curried()
。这就像someCallback()
在您的示例中一样。
这个花哨的术语是currying。
作为一个更有趣的示例,请考虑以下内容:
class Program {
static Func<TArg, TResult> Curry<TArg, TResult>(
Func<TArg, TArg, TResult> func,
TArg arg1
) {
return arg => func(arg1, arg);
}
static int Add(int x, int y) {
return x + y;
}
static void Main(string[] args) {
Func<int, int> addFive = Curry<int, int>(Add, 5);
Console.WriteLine(addFive(7));
}
}
在这里,我们声明了一个Curry
接受委托的方法(Func<TArg, TArg, TResult>
它接受两个相同类型的参数TArg
并返回一个其他类型的值TResult
和一个类型参数,TArg
并返回一个接受单个类型参数TArg
并返回一个类型值的委托TResult
(Func<TArg, TResult>
)。
然后,作为测试,我们声明一个Add
接受两个类型参数int
并返回一个类型参数int
(a Func<int, int, int>
) 的方法。然后,Main
我们实例化一个名为的新委托addFive
,它的作用类似于将 5 添加到其输入参数的方法。因此
Console.WriteLine(addFive(7));
12
在控制台上打印。