Come ho avuto modo di descrivere tempo fa in un articolo, la currificazione è una caratteristica che alcuni linguaggi di programmazione mettono a disposizione e che permette di invocare una funzione, che ha N parametri, specificando un numero M di valori con M <= N.
Facciamo un esempio con una sintassi astratta:
Add(x, y) = x + y
print Add(10, 20) // 30
print Add(10) // fn(y) = 10 + y
Se Add, che ha due parametri, viene invocata con un solo valore allora anzichè ritornare il risultato, ritorna una funzione che attende un solo argomento in cui un valore è già vincolato.
Non che abbia una particolare utilità ma la stessa cosa può essere replicata, con una sintassi semplice, anche in C# 3.0 facendo uso di lambda expression ed extension method. Vediamo un esempio:
class
Program
{
static int Add(int x, int y) { return x + y; }
static void Main(string[] args)
{
Func<int, int, int> f = Add;
Console.WriteLine(f1.Invoke(10, 20)); // 30
}
}
Il delegate Func<A0, A1, T> ha già un metodo Invoke che attende 2 argomenti. Se tentassi di invocarlo con un solo argomento (o con nessuno) solleverebbe un'eccezione. Proviamo allora ad aggirare il problema scrivendo un extension method che si chiama proprio Invoke:
public
static class FuncExtensions
{
public static Func<A1, T> Invoke<A0, A1, T>(this Func<A0, A1, T> func, A0 arg0)
{
return a1 => func(arg0, a1);
}
}
Questo overload del metodo Invoke è disponibile per tutti i delegate che sono convertibili a Func<A0, A1, T>, quindi anche il metodo Add. L'overload questa volta attende un solo valore e restituisce il riferimento ad un ulteriore metodo (la lambda expression). Possiamo quindi scrivere:
Func<int, int> f2 = f1.Invoke(10); // Chiamata currificata.
Console.WriteLine(f2(30)); // 40