Lambda is an anonymous function. Because there is no name or keyword to reference itself, recursive encoding becomes a problem.
I. the simplest and most effective solution is:
Func <int, int> f = null; // The variable must be assigned a value before f = n => n = 0? 1: n * f (n-1); f (11); // = 39916800
Some people worry that f will be maliciously modified. Because f is a delegate variable and is considered to be a delegate rather than an anonymous function, it is not considered an anonymous function recursion. In my opinion, although it is a delegate, the reference is an anonymous function. Isn't the function called by the function pointer itself?
2. To avoid malicious modification of variables, the solution is:
Func<int,int> f = null;f = n =>{Func<int,int> f2 = null;f2 = x=> x==0?1:x*f2(x-1);return f2;}f(11);
All are happy.
3. Wonderful work
Func<Func<int,int>,Func<int,int>> g = f => f = n => n==0?1:n*f(n-1);g(null)(11);
Iv. Fixed Point Technology
Func<T,R> Fx<T,R>(Func<Func<T,R>,Func<T,R>> g) { return x=>g(Fx(g))(x); }Func<Func<int,int>,Func<int,int>> g = f => n => n==0?1:n*f(n-1);Fx(g)(11);
Fx (g) returns x => g (fx (g) (x) that is g; f = fx (g ). Because fx (g) = x => g (fx (g) (x) is equal to g.
Therefore, f = g. That is, the function g (f) is equal to g (g) to call itself.
This fixed point technology is quite troublesome (difficult to understand) because of the defects of c # Language (generic parameter constraints cannot be delegation, etc.), Func cannot be generalized <T, R>, that is to say, recursive functions cannot be generalized, but need to write n Different Fx.
For example, Func <T1, T2, R> Fx <T1, T2, R> (Func <T1, T2, R>, Func <T1, T2, r> g.
The fixed point is successful because it generates a delegate equivalent to g. Fx (g) returns the delegate instead of the recursion itself, so it does not recursively overflow (I did not notice this at first ).