net 4.0 code contracts (2010)
TRANSCRIPT
.NET 4.0 Code ContractsKOEN METSU
Presentation provided byKoen Metsu
◦ Independent .NET consultant
◦ Blog: http://www.koenmetsu.com
◦ Twitter: @koenmetsu
AgendaIntroduction
Basic concepts
Code Contracts at work◦ Static checking
◦ Runtime checking
Advanced usage◦ Contract inheritance
◦ Customize contract runtime
◦ PEX
◦ Documentation Generation
◦ Contract reference assembly
Future
Resources
Maintaining proper internalstateProvider exposes ITrainScheduler
As consumer◦ Range of dates?◦ Is there a max resultset?◦ Can I provide an empty train name?
As provider◦ Raise exceptions on invalid input?◦ Debug.Assert to check internal state?◦ Reusability??
public interface ITrainScheduler{
IList<Train> GetScheduledTrains(DateTime start, DateTime end);void ScheduleTrain(string name, Route route);
}
Code Contracts to the rescue!1 language agnostic API
◦ same API for C#, VB.NET, F#, …◦ System.Diagnostics.Contracts
◦ mscorlib
Design By Contract◦ Define expectations from caller
◦ Make promises
◦ Maintain constant proper internal state
Benefits:◦ Testing (e.g. Pex)
◦ Documentation (e.g. SandCastle)
◦ Static checking
◦ Runtime checking
Very Basic conceptsObject
◦ State
◦ Behavior
Example: Dog◦ State
◦ Age
◦ Name
◦ Color
◦ Behavior◦ Bark
◦ Sit
◦ Drool
Basic ConceptsTypes of Contracts
Contracts in real lifeCUSTOMER
1) I want that new monitor
BIG MEDIASTORE EMPLOYEE
2) That’ll be 200€ please!
3) Thank you, your monitor will:◦ Have a remote
◦ Be brand new
Preconditions before Code ContractsValidating input parameters
◦ If … throw ArgumentException
◦ Lots of documentation
◦ Caller doesn’t know about valid input
Preconditions with Code ContractsValidating input
◦ Validates state on method entry
◦ Burden on caller, so must be about state visible to caller
Legacy code◦ Existing “If … then throw” can be integrated
◦ Contract.EndContractBlock();
Contract.Requires(!string.IsNullOrEmpty(text));Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(text));
Making promisesPostconditions
◦ Validates state on method exit
◦ Helper methods in Contracts assembly◦ Result<T>
◦ OldValue<T>
◦ ValueAtReturn<T>
Contract.Ensures(trainCount >5);Contract.Ensures(Contract.Result<Train>()!= null);
Maintaining proper stateObject Invariants
◦ Condition that holds at all (visible) time.
◦ On public method exits
[ContractInvariantMethod]private void SomeMeaningfulName(){
Contract.Invariant(CheckValidity());}
PurityAll contract checks must have no visible side-effects to callers
Declare purity with [Pure] on◦ Types
◦ Methods
Considered pure◦ Implicit
◦ Property getters
◦ Operators
◦ Methods of immutable types
◦ Explicit◦ Methods/Types declared pure
[Pure]private bool CheckValidity(string text){
//logic here}
QuantifiersForAll
◦ Condition must hold for all elements
Exists◦ Condition must hold for at least one element
Contract.Requires(Contract.ForAll(myEnumerable, x => x.IsValid));
Contract.Requires(Contract.Exists(myEnumerable, x => x.IsChosen));
Asserting your stateAssert
◦ Condition must be valid
Assume◦ Runtime checker
◦ same as Contract.Assert
◦ Static checker◦ Condition doesn’t have to be proven, it’s assumed to be true
Contract.Assert(myValue == expectedValue);
Contract.Assume(myValue == expectedValue);
Debug.Assert vsContract.AssertDebug.Assert
◦ Only in Debug builds
◦ No tools
◦ Works even with Code Contracts disabled
Contract.Assert◦ Can work in release builds (configurable)
◦ Tools
◦ Does not work with Code Contracts disabled
Code Contracts at work
Upon installationNew property pane
Static CheckingFinds contract breaches before running
Can run in background
◦ Shows warnings for◦ Unproven contracts
◦ Possible null references
◦ Possible out of bounds calls
◦ Redundant assumptions
◦ Implicit arithmetic obligations
Working with the static checkerCan be overwhelming
Fix warnings◦ Statistically provable
◦ Preconditions
◦ Postconditions
◦ Invariants
◦ Assumptions & Assertions
Baseline◦ Exclude current warnings
◦ Export to file
Runtime CheckingOn Failure:
◦ Throw ContractException◦ Internal class
◦ “not catchable”…
◦ … except by catching general exception
◦ Assert on Failure
REMINDER: BEST PRACTICEDO NOT CATCH GENERAL EXCEPTION
CCRewrite
CCRewrite
Advanced Usage
Contract InheritanceInterface does not show you the behavior
Contracts are inherited◦ Preconditions
◦ Can’t add extra ( Liskov Substition Principle )
◦ Postconditions & Invariants◦ Can be made stronger
Making your interfaces/abstracts behave
Dummy class, implementing interface◦ Contracts in method body
[ContractClass(typeof(IFooContract))]
[ContractClassFor(typeof(IFooContract))]
Usage in an existing projectEnable the baseline
◦ Stores all warnings during next run in an Xml file
◦ Warnings in the Xml file will not be shown again
Customize Contract Runtime Contract handling
Contract failure
Override Runtime Checking Behavior◦ Every Contract check
◦ ReportFailure method
◦ RaiseContractFailedEvent
PexAutomated White Box Testing
◦ Parameterized Unit Tests
◦ Analyzes code under test
Analyzes Code Contracts◦ 100% Code Contracts test coverage
◦ Tests target contract conditions
Suggests missing contracts
SandcastleMSDN style API documentation generation
◦ XML comments
◦ Enable XML documentation output
CodePlex◦ Sandcastle
◦ Sandcastle Helpfile Builder
Includes contract documentation
Isolate Contracts in SeperateAssemblyOption: generate a reference assembly
Ship when needed◦ Limit product size
◦ Debugging
Generates <AssemblyName>.Contracts.dll
Future of Code ContractsUsage
◦ Use it personally to document and test your code
◦ Great for interdeveloper use
Built-in support◦ .NET 4.0 BCL behavior defined by Code Contracts
◦ Supported in Silverlight 4
◦ VS add-in
Third party tools supporting Code Contracts◦ PEX, Sandcastle, Resharper
ResourcesCode Contracts
◦ Official site
Pex◦ Official site
◦ http://www.pexforfun.com
Sandcastle◦ Official site
◦ Sandcastle Helpfile Builder
Q&AQuestions?