В 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
.Как правило, Action<T>
- это делегат, который принимает один параметр типа T
и возвращает void
.В частности, Foo
является Action<int>
, поскольку он принимает один параметр типа int
и возвращает void
.Что касается типа возврата Curry
, он объявлен как Action
.Action
является делегатом, который не имеет параметров и возвращает void
.
Определение Curry
довольно интересно.Мы определяем действие, используя лямбда-выражение, которое представляет собой особую форму анонимного делегата.Фактически
() => action(parameter)
говорит, что параметр void
сопоставляется с action
, оцененным в parameter
.
Наконец, в Main
мы объявляем экземпляр Action
с именем curried
, который является результатом применения Curry
к Foo
с параметром 5
.Это играет ту же роль, что и bind(fun_ptr(foo), 5)
в вашем примере C ++.
Наконец, мы вызываем вновь сформированный делегат curried
через синтаксис curried()
.Это похоже на someCallback()
в вашем примере.
Причудливый термин для этого: curry .
В качестве более интересного примера рассмотрим следующее:
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
, который действует как метод, который добавляет пять к своему входному параметруТаким образом,
Console.WriteLine(addFive(7));
печатает 12
на консоли.