Solution 1 is pretty good but it leaves a vulnerability for error.
It depends on the binding to the name
factorialValue
for the recursive call.
If were
compromised it falls apart.
Very contrived example:
Func<int, int> Factorial = null;
Factorial = x => (x <= 0) ? 1 : x * Factorial(x - 1);
Func<int, int> incorrectFactorial = Factorial;
Factorial = x => x;
int ans = incorrectFactorial(5);
The value of
ans
here is 20 because of the reassignment of the identifier
Factorial
.
The name binding the recursive method needs to be protected:
Func<int, int> Factorial = null;
Factorial = x => {
Func<int, int> internalFactorial = null;
internalFactorial = xi => (xi <= 0) ? 1 : xi * internalFactorial(xi - 1);
return internalFactorial(x);
};
Func<int, int> otherFactorial = Factorial;
Factorial = x => x;
int ans = otherFactorial(5);
Here the value of
ans
is the correct 120 because the recursion identifier was internal to the scope of the lambda.
Another way to accomplish this would be to have a method that returns a
Func<int, int>
:
static Func<int, int> GetFactorialFunction()
{
Func<int, int> Factorial = null;
Factorial = x => (x <= 0) ? 1 : x * Factorial(x - 1);
return Factorial;
}
and invoke the returned function:
int ans = GetFactorialFunction()(5);
Of course, at this point using a lambda is
probably superfluous since the function could be implemented directly as a named, recursive function.