Why should I use code contracts like
Contract.Requires<ArgumentNullException>( x != null, "x" );
instead of good old
if (x!=null){}
else throw...
Are there any other benefits except of conciseness ?
According to the MSDN:
The benefits of code contracts include the following:
- Improved testing: Code contracts provide static contract verification, runtime checking, and documentation generation.
- Automatic testing tools: You can use code contracts to generate more meaningful unit tests by filtering out meaningless test arguments that do not satisfy preconditions.
- Static verification: The static checker can decide whether there are any contract violations without running the program. It checks for implicit contracts, such as null dereferences and array bounds, and explicit contracts.
- Reference documentation: The documentation generator augments existing XML documentation files with contract information. There are also style sheets that can be used with Sandcastle so that the generated documentation pages have contract sections.
Your mileage may vary which of those points are important or not. I found the third and fourth (static verification and documentation) especially interesting.
In other words, it is more structured way of describing contracts (instead of constructs like if (x!=null){}
) that additional tools are able to understand.
Apart from syntactic sugar, Code Contracts is Microsoft's tool for for "Design by Contract" paradigm. http://en.wikipedia.org/wiki/Design_by_contract
It basically a different a way of thinking when you design your classes and operations. From experience, DbC works very well with Test Driven Development, with you basically defining contracts and writing tests for it before you write any business logic.
Behind the scenes, Contract contract generates code similar to your good old code at compile time, so IL code contains all the checks.
For example, the class
public class Scheduler
{
public bool ScheduleTask(string taskname, DateTime startTime, DateTime endTime)
{
Contract.Requires(!string.IsNullOrWhiteSpace(taskname));
Contract.Requires(startTime != null);
Contract.Requires(endTime != null);
return true;
}
}
Will result in something like
public bool ScheduleTask(string taskname, DateTime startTime, DateTime endTime)
{
__ContractsRuntime.Requires(!string.IsNullOrWhiteSpace(taskname), null, "!string.IsNullOrWhiteSpace(taskname)");
__ContractsRuntime.Requires(true, null, "startTime != null");
__ContractsRuntime.Requires(true, null, "endTime != null");
return true;
}
where _ContractsRuntime.Requests look like following
internal static void Requires(bool condition, string msg, string conditionTxt)
{
if (!condition)
{
__ContractsRuntime.ReportFailure(ContractFailureKind.Precondition, msg, conditionTxt, null);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With