This document summarizes a presentation about .NET 4.0 Code Contracts. The presentation introduces Code Contracts, including basic concepts like preconditions, postconditions, and object invariants. It demonstrates how to use Code Contracts to validate method parameters and return values, maintain object state, and assert conditions. The presentation also covers advanced topics such as contract inheritance, customizing runtime checking, using Code Contracts with tools like PEX and Sandcastle, and planning for the future of Code Contracts.
4. Maintaining proper internal
state
Provider exposes ITrainScheduler
public interface ITrainScheduler
{
IList<Train> GetScheduledTrains(DateTime start, DateTime end);
void ScheduleTrain(string name, Route route);
}
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??
5. 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
6. Very Basic concepts
Object
State
Behavior
Example: Dog
State
Age
Name
Color
Behavior
Bark
Sit
Drool
8. Contracts in real life
CUSTOMER
1) I want that new monitor
BIG MEDIASTORE EMPLOYEE
2) Thatll be 200 please!
3) Thank you, your monitor will:
Have a remote
Be brand new
9. Preconditions before Code
Contracts
Validating input parameters
If throw ArgumentException
Lots of documentation
Caller doesnt know about valid input
10. Preconditions with Code
Contracts
Validating input
Validates state on method entry
Burden on caller, so must be about state visible to caller
Contract.Requires(!string.IsNullOrEmpty(text));
Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(text));
Legacy code
Existing If then throw can be integrated
Contract.EndContractBlock();
11. Making promises
Postconditions
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);
12. Maintaining proper state
Object Invariants
Condition that holds at all (visible) time.
On public method exits
[ContractInvariantMethod]
private void SomeMeaningfulName()
{
Contract.Invariant(CheckValidity());
}
13. Purity
All 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
}
14. Quantifiers
ForAll
Condition must hold for all elements
Contract.Requires(Contract.ForAll(myEnumerable, x => x.IsValid));
Exists
Condition must hold for at least one element
Contract.Requires(Contract.Exists(myEnumerable, x => x.IsChosen));
15. Asserting your state
Assert
Condition must be valid
Contract.Assert(myValue == expectedValue);
Assume
Runtime checker
same as Contract.Assert
Static checker
Condition doesnt have to be proven, its assumed to be true
Contract.Assume(myValue == expectedValue);
16. Debug.Assert vs
Contract.Assert
Debug.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
19. Static Checking
Finds 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
20. Working with the static
checker
Can be overwhelming
Fix warnings
Statistically provable
Preconditions
Postconditions
Invariants
Assumptions & Assertions
Baseline
Exclude current warnings
Export to file
21. Runtime Checking
On Failure:
Throw ContractException
Internal class
not catchable
except by catching general exception
Assert on Failure
REMINDER: BEST PRACTICE
DO NOT CATCH GENERAL EXCEPTION
24. Contract Inheritance
Interface does not show you the behavior
Contracts are inherited
Preconditions
Cant add extra ( Liskov Substition Principle )
Postconditions & Invariants
Can be made stronger
Making your interfaces/abstracts behave
[ContractClass(typeof(IFooContract))]
Dummy class, implementing interface
Contracts in method body
[ContractClassFor(typeof(IFooContract))]
25. Usage in an existing project
Enable the baseline
Stores all warnings during next run in an Xml file
Warnings in the Xml file will not be shown again
27. Pex
Automated 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
28. Sandcastle
MSDN style API documentation generation
XML comments
Enable XML documentation output
CodePlex
Sandcastle
Sandcastle Helpfile Builder
Includes contract documentation
29. Isolate Contracts in Seperate
Assembly
Option: generate a reference assembly
Ship when needed
Limit product size
Debugging
Generates <AssemblyName>.Contracts.dll
30. Future of Code Contracts
Usage
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
31. Resources
Code Contracts
Official site
Pex
Official site
http://www.pexforfun.com
Sandcastle
Official site
Sandcastle Helpfile Builder
Expectations for Interfaces vsClasses
.NET interfaces dont contain implementation details. But, isnt the fact that a particular methods argument and return value should never ever be null a concern of the interface definition and not the classes that implement it?
Code Contracts are checked in this sequence
CODESAMPLE:
Show if throw argumentexception
Take note of the amount of documentation. ( this is a public api youre writing )
Code Sample
CODE SAMPLE:
- show how to write postcondition
- Put emphasis on validating your own code
Worden in begin method geplaatst, check gebeurt wel degelijk op einde
Hoewel preconditions ( validating input ) gemakkelijk te implementeren is zonder Code Contracts, zijn postconditions moeilijker: oorspronkelijke waarden zelf bijhouden, wat bij foutieve staat,
All preconditions and postconditions are expressed before the main
implementation in Code Contracts. The tools assume that anything that comes after
the last reference to Contract (apart from calls to Assert and Assume, which
we'll meet in a minute) is part of the implementation, but anything up to that point
is purely contractual and has no impact on the real work of the method. If you
mistakenly put a postcondition at the end of the method, Code Contracts will
complain of a "malformed contract."
Invariants are contracts about the state of the object
which should apply at all times that the state is visible. In other words, it's okay to
change an invariant while a public method in the class is running, but at the end of
the method the invariant should satisfied again.
Purity will be checked in the future
Contract.Assert versus Debug.Assert
- Release build kan Contract.Asserts bevatten (geen Debug.Asserts)
- Static / Runtime checker zoekt naar Contract.Asserts, niet naar Debug.Asserts
- Als Contracts disabled zijn, worden Debug.Asserts (in debug builds) wel nog uitgevoerd
Up until now, Code Contracts did not do anything. We just declared them, but as such, they do nothing.
Its only with the Code Contract tools they actually do anything besides documenting your code.