Code contracts by Dmytro Mindra

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 !