I'm playing around with Code Contracts at the moment and I'm not completely sure whether the static methods of the Contract class are powerful enough to compete with mathematical notation of conditions.
Let's assume we got a simple factorial method
int Factorial(int n);
I would express the following conditions:
Precondition:
n >= 0
Postconditions:
Factorial(n) = 1, in case n = 0
Factorial(n) = n*(n-1)*...*1, in case n > 0
These conditions clearly specify the behavior of Factorial in a short and clean way. My question is, whether they can be expressed through Code Contracts.
The precondition is trivial:
Contract.Requires(n >= 0)
The conditional post condition might be expresses using
if(n==0)
Contract.Ensures(Contract.Result<int>() == 1);
if(n > 0)
...
But I don't like the way I need the "if" statement here as it makes the plain list of pre- and postconditions harder to read. I hoped we would have something like
Contract.Ensures(...).InCase(...);
And last but not least, I do not have any idea how to express this, which is a common notation regarding math:
n*(n-1)*...*1
Guess I would need some kind of loop, but this would copy the whole implementation. Is there any smart way to express such notations?
Thank you in advance.
You could try to the following:
Contract.Ensures(Contract.Result<int>() == AlternativeFactorial(n));
where AlternativeFactorial
is:
[Pure]
public static int AlternativeFactorial(int n)
{
if(n==0)
return 1;
if(n > 0)
{
//Alternative implementation.
}
}
Of course anything you use in a contract should be side-effect free (pure).
Now as far as the factorial implementation, I cannot come up with a more compact "alternative" implementation than w0lf's. What you should consider though is changing the return value of your method from int to BigInteger. Factorials can get very large very quickly. Also note that by adding a post-condition on the factorial value, you will pretty much double the time your method will take to return a result. This can be resolved by building CodeContracts
only on the debug configuration.