En C# nous faisons quelque chose comme ceci:
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();
}
}
Il est clair que la méthode Foo
correspond à votre méthode Foo
, juste avec les appels appropriés à Console.WriteLine
au lieu de std::cout
. Ensuite, nous déclarons une méthode Curry
qui accepte un Action<T>
et renvoie un Action
. En général, un Action<T>
est un délégué qui accepte un seul paramètre de type T
et renvoie void
. En particulier, Foo
est un Action<int>
car il accepte un paramètre de type int
et renvoie void
. En ce qui concerne le type de retour de Curry
, il est déclaré comme Action
. Un Action
est un délégué qui n'a aucun paramètre et renvoie void
.
La définition de Curry
est plutôt intéressante. Nous définissons une action en utilisant une expression lambda qui est une forme très spéciale d'un délégué anonyme. En effet
() => action(parameter)
dit que le paramètre void
est mis en correspondance action
évaluée à parameter
.
Enfin, Main
nous déclarons une instance de Action
nommé curried
qui est le résultat de l'application Curry
à Foo
avec le paramètre 5
. Cela joue le même rôle que bind(fun_ptr(foo), 5)
dans votre exemple C++.
Enfin, nous appelons le nouveau délégué curried
via la syntaxe curried()
. C'est comme someCallback()
dans votre exemple.
Le terme fantaisie pour cela est currying.
A titre d'exemple plus intéressant, tenez compte des éléments suivants:
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));
}
}
Ici, nous proclamons une méthode Curry
qui accepte un délégué (Func<TArg, TArg, TResult>
qui accepte deux paramètres du même type TArg
et renvoie une valeur d'un autre taper TResult
et un paramètre de type TArg
et renvoie un délégué qui accepte un seul paramètre de type TArg
et renvoie une valeur de type TResult
(Func<TArg, TResult>
).
Puis, en tant que test, nous déclarons une méthode Add
qui accepte deux paramètres de type int
et renvoie un paramètre de type int
(un Func<int, int, int>
). Ensuite, dans Main
, nous instancions un nouveau délégué nommé addFive
qui agit comme une méthode qui ajoute cinq à son paramètre d'entrée. Ainsi,
Console.WriteLine(addFive(7));
imprime 12
sur la console.
Merci pour votre réponse détaillée. J'ai marqué l'autre comme la réponse acceptée parce qu'elle est plus concise, bien qu'il manque certains détails importants que vous avez inclus. – Catskul
Bien sûr. J'espère juste que la couleur supplémentaire aide. :-) – jason
Réponse extrêmement utile, ceci. Introduit un concept génial, currying, d'une manière facile à comprendre. Va certainement ajouter cela à ma boîte à outils mentale. –