View
659
Download
2
Category
Preview:
Citation preview
Code Contracts
Dmytro MindraRnD Tech Lead
Lohika Labs
Пятая встреча Microsoft .Net User Group Одесса, 2011
© Drake Emko & Jen Brodzik, 2001
© Drake Emko & Jen Brodzik, 2001
© Drake Emko & Jen Brodzik, 2001
Design by Contract
Bertrand MeyerDbC authorPublished 11 booksincluding “Object-Oriented
Software Construction”
First edition: 1988Second edition: 1997
Terms
• Client must pay the fee (obligation) and is entitled to get the product (benefit).
• Supplier must provide a certain product (obligation) and is entitled to expect that the client has paid its fee (benefit)
• Contract. Both parties must satisfy certain obligations, such as laws and regulations, applying to all contracts
Terms
Client«interface»Interface Supplier
Contract
• Contract is precise and verifiable interface specifications for software components, which extend the ordinary definition of abstract data types with preconditions, postconditions and invariants. [8]
Contract
• Pre-conditions [9]In computer programming, a precondition is a condition or predicate that must always be true just prior to the execution of some section of code or before an operation in a formal specification.
• Post-conditions [10]In computer programming, a postcondition is a condition or predicate that must always be true just after the execution of some section of code or after an operation in a formal specification.
• Invariants [11]In computer science, a predicate is called an invariant to a sequence of operations provided that: if the predicate is true before starting the sequence, then it is true at the end of the sequence.
Contract verification
• Pre-condition fails– Error in client code
• Post-condition or Invariant fails – Error in supplier code
Other approaches
• IF-THEN-TROWif(condition1)
throw Exception1if (condition2)
throw Exception2
• Debug.Assert
• Drawbacks:– No Inheritance– Inconvenient postconditions
Converting legacycontracts
Converting if-throw
void MyMethod(Foo foo){ if (foo == null) throw new ArgumentNullException(...); Contract.EndContractBlock();
... normal method code ...}
Spec#
class Example { int x;
void Inc(int y) ensures old(x) < x; { x += y; }}
New Generation
• Spec#– Source code rewrite– C# only (superset of C#
v2.0)
• Code Contracts– IL Rewrite– Any language from VB to
C#– Faster
Code Contracts
How to start using Code Contracts ?
Visual Studio 2010
• Declarative contracts are included in .NET 4.0 (System.Diagnostics.Contracts)
• Tools are needed to – generate runtime checking from the
contracts(ccrewrite)– do a static check that verifies contracts at compile-
time (cccheck)– add contracts to the XML documentation files (ccdoc)LOCATION: [Program Files]\Microsoft\Contracts\Bin\
System.Diagnostics.Contracts• Contract• Attributes
– ContractClassAttribute– ContractClassForAttribute– ContractInvariantMethodAttribute– ContractPublicPropertyNameAttribute– ContractReferenceAssemblyAttribute– ContractRuntimeIgnoredAttribute– ContractVerificationAttribute– PureAttribute ( is not enforced by analysis tools )
• ContractFailedEventArgs• ContractFailureKind (enum)
Contract methods
• Pre-conditions: Requires• Post-conditions: Ensures• Invariants: Invariant
See also: EnsuresOnThrow<TException>Requires<TException>
Preconditions in Action public class Customer {
private int _ID; public int ID { get { return _ID; } set { if (value <= 0) throw new ArgumentException(); _ID = value; } }}
public class Customer{ private int _ID; public int ID { get { return _ID; } set {
Contract.Requires(value > 0);
_ID = value; } }}
Demo: Basic + IL Spy
Processing collections
• Integer range– ForAll(Int32, Int32, Predicate<Int32>)– Exists(Int32, Int32, Predicate<Int32>)
• CollectionForAll<T>(IEnumerable<T>, Predicate<T>)Exists<T>(IEnumerable<T>, Predicate<T>)
Demo: Collections
Result processing
• OldValue<T>• Result<T>• ValueAtReturn<T>
Demo: Results
Other
• Assert - Checks for a condition• Assume - Instructs code analysis tools to
assume that the specified condition is true, even if it cannot be statically proven to always be true. Only for static checks. In runtime is treated like Assert. [3]
• EndContractBlock - for legacy contracts
Assert & Assumepublic void Invoke() {
int x = CalculateSomeValues(); // Tell the checker to verify whether// x>0. // (The checker might // be unable to do it.)
Contract.Assert( x>0 );
// Rest of the code }
public void Invoke() {
int x = CalculateSomeValues(); // Explicitly tell the checker that //x>0
Contract.Assume( x>0 );
// Rest of the code }
Inheritance
• Two rules[7]:– When you override a method (or implement an
interface method) you inherit its contracts.– You can't add extra preconditions to inherited
ones, but you can make invariants and postconditions stronger. • E.g was require x>10• Added require x>100• Now x = 20 fulfills 1st require but violates 2nd;
Demo: Inheritance& Pitfalls
ContractFailed Handling
Contract.ContractFailed += ContractContractFailed;
static void ContractContractFailed(object sender, ContractFailedEventArgs
e) { e.SetHandled(); // exception handled
Console.WriteLine(e.Message);}
Demo: ContractFailedfandling
custom contracts &custom rewriters methods
public static class RuntimeFailureMethods { public static void Requires(bool cond, string userMsg, string condText) { } public static void Ensures(bool cond, string userMsg, string condText) { }…
}See user manual 7.7. (page 34) [12]
Code snippets
• cr Contract.Requires(...);• ce Contract.Ensures(...);• ci Contract.Invariant(...);
• More in user manual 6.3. (page 26) [12]
Why not validate everything?
• Performance!
Summary and prospects
• Code Contracts are evolving• BCL is driven by Code Contracts• Static checking• Code Contracts may lead to better design• Auto generated documentation• Another tool in your toolbelt
PEXPath-based program exploration
Pex Demo
Additional reading
References[1] Design by Contract - A Conversation with Bertrand Meyer, Part II by Bill Vennershttp://www.artima.com/intv/contracts.html[2] Defensive programminghttp://en.wikipedia.org/wiki/Defensive_programming[3] Dino Esposito, Code Contracts Preview: Preconditionshttp://dotnetslackers.com/articles/net/Code-Contracts-Preview-Preconditions.aspx[4] Dino Esposito, Code Contracts Preview: PostConditionshttp://dotnetslackers.com/articles/net/Code-Contracts-Preview-PostConditions.aspx[5] Dino Esposito, Code Contracts Preview: Invariantshttp://dotnetslackers.com/articles/net/Code-Contracts-Preview-Invariants.aspx[6] Dino Esposito, Code Contracts Preview: Assert & Assumehttp://dotnetslackers.com/articles/net/Code-Contracts-Preview-Assert-Assume.aspx[7] Jon Skeet, Code Contracts in C#http://www.infoq.com/articles/code-contracts-csharp
References[8] Design by Contract - Wikipediahttp://en.wikipedia.org/wiki/Design_by_contract[9] Precondition - Wikipediahttp://en.wikipedia.org/wiki/Precondition[10] Postcondition - Wikipediahttp://en.wikipedia.org/wiki/Postcondition[11] Invariant - Wikipedia http://en.wikipedia.org/wiki/Invariant_(computer_science)[12] Code Contracts User Manualhttp://research.microsoft.com/en-us/projects/contracts/userdoc.pdf[13] Code contracts and inheritancehttp://stefanoricciardi.com/2009/07/17/code-contracts-and-inheritance/[14] Assertions in Managed Codehttp://msdn.microsoft.com/en-us/library/ttcc4x86.aspx
C# 4.0 in a nutshell
Page 508
Object-Oriented Software Construction
Object-Oriented Software ConstructionBertrand Meyer1988,1997
QUESTIONS ?
THANK YOU !
Recommended