Anonymous Recursion in C#在这个话题上有很好的讨论。
递归很漂亮,lambda是 的最终抽象。但 他们怎么可以一起使用? Lambda表达式是 匿名函数和递归 需要的名字......
由于这再次弹起,这里使用的Y组合子的例子:
// This is the combinator
public static Func<A,R> Y<A,R>(Func<Func<A,R>, Func<A,R>> f)
{
Func<A,R> g = null;
g = f(a => g(a));
return g;
}
这里的它的使用来调用匿名递归函数...
Func<int,int> exp = Y<int,int>(e => x => (x <=1) ? 1 : x * e(x - 1));
Console.WriteLine(exp(5));
你会注意到,如果你不使用的Y组合子,并成立了递归只委托,你没有得到CORRE ct递归。例如...
但一切工作正常...
Console.WriteLine(badRec(5));
// Output
// 120
但试试这个...
Func<int,int> badRec = null;
badRec = x => (x <= 1) ? 1 : x * badRec(x - 1);
Func<int,int> badRecCopy = badRec;
badRec = x => x + 1;
Console.WriteLine(badRec(4));
Console.WriteLine(badRecCopy(5));
// Output
// 5
// 25
什么?!?
你看,行badRec = x => x + 1;
后,你确实有委托是这样的......
badRecCopy = x => (x <= 1) ? 1 : x * ((x+1)-1);
所以,badRec由1我们预计(4+1=5)
增加值,但是现在badRecCopy实际上返回价值(5*((5+1)-1)
的平方,我们几乎可以肯定没有想到。
如果您使用的Y组合子,它会如预期...
Func<int,int> goodRec = Y<int,int>(exp => x => (x <=1) ? 1 : x * exp(x - 1));
Func<int,int> goodRecCopy = goodRec;
,你会得到你所期望的。
goodRec = x => x + 1;
Console.WriteLine(goodRec(4));
Console.WriteLine(goodRecCopy(5));
// Output
// 5
// 120
您可以阅读更多关于Y-combinator(PDF链接)。
从VS2008确切的抱怨是:局部变量“构建”可能不被初始化之前访问。 – Matt 2009-07-30 19:15:33