Вы просто создаете перегруженную версию метода Memoize, которая имеет три универсальных типа и принимает функцию с двумя параметрами и двумя аргументами. Он по-прежнему возвращает функцию без параметров:
public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2)
{
R value = default(R);
bool hasValue = false;
return () =>
{
if (!hasValue)
{
hasValue = true;
value = f(a1,a2);
}
return value;
};
}
Edit:
В качестве альтернативы вам нужно создать собственный IEqualityComparer для KeyValuePair, который содержит два аргумента, чтобы метод Memoize мог возвращать функцию с двумя параметрами:
public static Func<A1,A2,R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, IEqualityComparer<KeyValuePair<A1,A2>> comparer)
{
var map = new Dictionary<KeyValuePair<A1,A2>,R>(comparer);
return (a1,a2) =>
{
R value;
KeyValuePair<A1,A2> key = new KeyValuePair<A1,A2>(a1,a2);
if (map.TryGetValue(key, out value)) {
return value;
}
value = f(a1,a2);
map.Add(key, value);
return value;
};
}