4

在 C# 中,我如何记住一个带有两个参数的函数?

在记忆之前我必须咖喱吗?

Wes Dyer 编写了我通常使用的 Memoization 代码,但现在我需要两个参数

4

5 回答 5

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;
    };
}

编辑:
或者,您需要为包含两个参数的 KeyValuePair 制作自定义 IEqualityComparer,以便 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;
      };
}
于 2009-03-11T06:22:54.253 回答
5

Wes 有另一个帖子,他给出了两个(或更多)参数版本的 Memoize。它不需要自定义比较器。

于 2009-03-11T13:29:58.827 回答
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;
        };
    }
于 2010-10-14T20:19:34.377 回答
2

你应该能够记住一对。这两个 arg 函数调用您记忆的单个 arg 函数。

于 2009-03-11T06:21:07.003 回答
1

我还在 C# 中做了一些关于记忆的工作。我的结果相似,但使用了从输入对象哈希码的串联派生的字典键。该模式可以扩展到 Func<> 允许的尽可能多的输入。

在这里查看更多信息:http: //bit.ly/t6iNJP

于 2011-10-28T12:58:39.317 回答