Памятка с двумя аргументами - PullRequest
4 голосов
/ 11 марта 2009

В C # как запомнить функцию с двумя аргументами?

Нужно ли карри перед запоминанием?

Уес Дайер написал код Memoization Я обычно использую, но теперь мне нужно два аргумента

Ответы [ 5 ]

5 голосов
/ 11 марта 2009

Вы просто создаете перегруженную версию метода 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;
      };
}
5 голосов
/ 11 марта 2009

У Уэса есть другой пост, где он дает версию Memoize с двумя (или более) аргументами . Не требует специального компаратора.

3 голосов
/ 15 октября 2010

С новыми версиями .NET вы можете немного упростить код принятого решения с помощью кортежей

    public static Func<TParam1, TParam2, TReturn> Memoize<TParam1, TParam2, TReturn>(Func<TParam1, TParam2, TReturn> func)
    {
        var map = new Dictionary<Tuple<TParam1, TParam2>, TReturn>();
        return (param1, param2) =>
        {
            var key = Tuple.Create(param1, param2);
            TReturn result;
            if (!map.TryGetValue(key, out result))
            {
                result = func(param1, param2);
                map.Add(key, result);
            }
            return result;
        };
    }
2 голосов
/ 11 марта 2009

Вы должны иметь возможность запомнить пару. Функция двух arg вызывает одну функцию arg, которую вы запомнили.

1 голос
/ 28 октября 2011

Я также проделал некоторую работу по запоминанию в C #. Мои результаты похожи, но я использую ключ словаря, полученный из конкатенации хеш-кодов входных объектов Шаблон может быть расширен на столько входов, сколько позволит Func <>.

Смотри еще здесь: http://bit.ly/t6iNJP

...