在C#中,我可以包装Func以缓存结果吗
我编写了返回计算整数序列的在C#中,我可以包装Func以缓存结果吗,c#,func,C#,Func,我编写了返回计算整数序列的Func的代码。我希望以最优雅的方式缓存中间结果。当前我的代码如下所示: 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
Func
的代码。我希望以最优雅的方式缓存中间结果。当前我的代码如下所示:
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;
}
private static Func A237585(){
Func A=null;
Func B=null;
Func 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));
返回A;
}
私有静态Func CreateCachingFunc(Func原始)
{
var cache=新列表();
Func cachedVersion=(n)=>
{
而(n>=cache.Count)cache.Add(original(cache.Count));
返回缓存[n];
};
返回cachedVersion;
}
我希望它看起来像这样:
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;
}
private static Func A237585(){
CachedFunc A=null;
CachedFunc B=null;
CachedFunc 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));
返回A;
}
可能吗?如何编写CachedFunc以在返回时隐式地将CachedFunc转换回Func,并隐式地将匿名lambda转换(包装)为缓存版本?如果这是不可能的,那么包装我的函数的最好方式是什么?我希望顶层代码看起来尽可能简单。首先让我们将使用lambda的现有备忘录实现转换为显式捕获类(这与C编译器在看到lambda时自动创建的几乎相同):
类CachedFunc
{
私有列表缓存;
私人Func原件;
私人电话(int n)
{
而(n>=cache.Count)cache.Add(original(cache.Count));
返回缓存[n];
}
公共静态函数创建(函数原始)
{
返回new CachedFunc(){cache=new List(),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;
}
}
类CachedFunc
{
私有列表缓存;
私人Func原件;
私人电话(int n){
而(n>=cache.Count)cache.Add(original(cache.Count));
返回缓存[n];
}
公共静态隐式运算符CachingFunc(Func-original)
{
返回new CachedFunc(){cache=new List(),original=original};
}
公共静态隐式运算符Func(CachingFunc memo)
{
回信备忘录。电话;
}
}
这是家庭作业吗?你的代码怎么了?你如何衡量“最优雅”和“尽我所能的简单”?这叫做记忆化。我正在寻找新的有趣的序列添加到OEIS中。这个是我的。总的来说,我希望有一段外观非常简单的代码作为主要描述,并带有到其余实现的链接。如果您不想为此推出自己的解决方案,那么有一些记忆库,比如MbCache();CachedFunc B=null;CachedFunc 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));返回A;分配A表示“B是一个变量,但像方法一样使用”。分配B表示“无法将lambda表达式转换为CachedFunc类型,因为它不是委托类型”。分配C很好。@Guy:不能在C#中使用户定义的对象可调用。但是使用B.Call(n-1)
(当然要公开)。一个扩展方法可能有助于从lambdas分配这些对象。@Guy:BTW,如果您将名称CreateCachingFunc
缩短为例如memo