2009-03-11 5 views

ответ

5

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

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

5

У Уэс есть еще одна почта, где он дает a two (or more) argument version of Memoize. Он не требует специального сравнения.

+0

Да, этот код намного лучше Wes. Вы и Гуффа верны, но Гуффа приложил больше усилий, поэтому я награждаю его. Спасибо хоть! – CVertex

3

С новыми версиями .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; 
     }; 
    } 
1

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

Se больше здесь: http://bit.ly/t6iNJP

Смежные вопросы