Alternative (to tuples & anonymous types) approach might be as follows:
static void Main(string[] args)
{
var func = Memoize(Func);
Console.WriteLine(func(3)(4));
Console.WriteLine(func(3)(5));
Console.WriteLine(func(2)(5));
Console.WriteLine(func(3)(4));
}
//lets pretend this is very-expensive-to-compute function
private static int Func(int i, int j)
{
return i + j;
}
private static Func> Memoize(Func func)
{
Func> func1 =
Memoize((TArg1 arg1) => Memoize((TArg2 arg2) => func(arg1, arg2)));
return func1;
}
private static Func Memoize(Func func)
{
var cache = new Dictionary();
return arg =>
{
TRes res;
if( !cache.TryGetValue(arg, out res) )
{
Console.WriteLine("Calculating " + arg.ToString());
res = func(arg);
cache.Add(arg, res);
}
else
{
Console.WriteLine("Getting from cache " + arg.ToString());
}
return res;
};
}
Based on these two Memoize funcs you can easily build extensions for as many args as you wish.