我编写了返回 Func<int, long>
的代码计算整数序列。我想以最优雅的方式缓存中间结果。目前我的代码如下所示:
private static Func<int, long> A237585() {
Func<int, long> A = null;
Func<int, long> B = null;
Func<int, long> C = null;
A = CreateCachingFunc((n) => n == 0 ? 0 : B(n-1));
B = CreateCachingFunc((n) => C(n) + (n == 1 ? 1 : 0));
C = CreateCachingFunc(CreateSumProductPartitionSelect(A, (n, k) => Choose(n + k - 1, k)));
return A;
}
private static Func<int, long> CreateCachingFunc(Func<int, long> original)
{
var cache = new List<long>();
Func<int, long> cachedVersion = (n) =>
{
while (n >= cache.Count) cache.Add(original(cache.Count));
return cache[n];
};
return cachedVersion;
}
我希望它看起来像这样:
private static Func<int, long> A237585() {
CachedFunc<long> A = null;
CachedFunc<long> B = null;
CachedFunc<long> C = null;
A = (n) => n == 0 ? 0 : B(n-1);
B = (n) => C(n) + (n == 1 ? 1 : 0);
C = CreateSumProductPartitionSelect(A, (n, k) => Choose(n + k - 1, k));
return A;
}
这可能吗?我将如何编写 CachedFunc 以在返回时将 CachedFunc 隐式转换回 Func,并将匿名 lambda 隐式转换(包装)为缓存版本?如果不可能,那么包装我的函数的最好看的方式是什么?我希望顶层代码看起来尽可能简单。
最佳答案
让我们首先将使用 lambda 的现有内存实现转换为显式捕获类(这与 C# 编译器在看到 lambda 时自动创建的类几乎相同):
class CachedFunc<T>
{
private List<T> cache;
private Func<int, T> original;
private T Call(int n)
{
while (n >= cache.Count) cache.Add(original(cache.Count));
return cache[n];
}
public static Func<int, long> Create(Func<int, T> original)
{
return new CachedFunc<T>() { cache = new List<T>(), original = original }.Call;
}
}
现在,我们只需要添加隐式转换:
class CachedFunc<T>
{
private List<T> cache;
private Func<int, T> original;
private T Call(int n) {
while (n >= cache.Count) cache.Add(original(cache.Count));
return cache[n];
}
public static implicit operator CachingFunc<T>(Func<int, T> original)
{
return new CachedFunc<T>() { cache = new List<T>(), original = original };
}
public static implicit operator Func<int, T>(CachingFunc<T> memo)
{
return memo.Call;
}
}
关于c# - 在 C# 中,我可以包装 Func 来缓存结果吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21816817/