100 likes | 226 Views
Code Contract Introduction. Specification of a Person Class. Installation. Download from this URL: http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx. Installation. Get it!. You can get documentation and much more:. Visual Studio. Use this namespace
E N D
Code Contract Introduction Specification of a Person Class UCN T&B - PBA/CodeContract-Intro
Installation • Download from this URL: http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx UCN T&B - PBA/CodeContract-Intro
Installation Get it! UCN T&B - PBA/CodeContract-Intro You can get documentation and much more:
Visual Studio Use this namespace Add a reference to Microsoft.Contracts In VS2012, you don’t have to add the reference, if you target the .NET 4.5 framework. Contracts is now part the v4.5 mscorelib.dll UCN T&B - PBA/CodeContract-Intro
Right-click on the project and choose ‘Properties’, then choose ‘ Code Contracts’ Chooseyoursettings! UCN T&B - PBA/CodeContract-Intro
Specification and implementation are bundled together. This is not nice!!! class Person { private String name; private int weight; public int Weight { get; private set; } [ContractInvariantMethod] private void ObjectInvariant() { Contract.Invariant(!name.Equals("") && weight >= 0); } [Pure] public override String ToString() { Contract.Ensures( Contract.Result <string>() != null); return "Person(\"" + name + "\"," + weight + ")"; } [Pure] public int GetWeight() { Contract.Ensures(Contract.Result<int>() == weight); return weight; } public void AddKgs(intkgs) { Contract.Requires(kgs >= 0); Contract.Requires(weight+kgs >= 0); Contract.Ensures(weight == Contract.OldValue(weight) + kgs); weight = weight + kgs; } public Person(String n) { Contract.Requires(n != null && !n.Equals("")); Contract.Ensures(n.Equals(name) && weight == 0); name = n; weight = } UCN T&B - PBA/CodeContract-Intro
Separate specification and implementation Telling that here is a contract [ContractClass(typeof(IPersonContract))] interface Iperson { ///<summary> ///@ also ///@ ensures \result != null; ///</summary> [Pure] String ToString(); ///<summary> ///@ ensures \result >= 0; ///</summary> [Pure] //Contract.Ensures(Contract.Result<int>() >= 0); int GetWeight(); ///<summary> /// /*@ requires kgs >= 0; /// @ ensures getWeight() == (\old(getWeight()) + kgs); /// @*/ ///</summary> void AddKgs(int kgs); } What we would like: Specification in an interface But specs in Code Contract are method calls, and method calls are not allowed in interfaces...? UCN T&B - PBA/CodeContract-Intro
interface Iperson { [Pure] String ToString(); intGetWeight(); void AddKgs(intkgs); } [ContractClassFor(typeof(IPerson))] internal abstract class IPersonContract : IPerson { [ContractInvariantMethod] private void ObjectInvariant() { Contract.Invariant(GetWeight() >= 0); } public override String ToString() { Contract.Ensures(Contract.Result<string>() != null); return default(string); } public intGetWeight() { Contract.Ensures(Contract.Result<int>() >=0); return default(int); } public void AddKgs(intkgs) { Contract.Requires(kgs >= 0); Contract.Requires(GetWeight()+kgs >= 0); Contract.Ensures(GetWeight() == Contract.OldValue(GetWeight()) + kgs); } } Spec in internal abstract class with dummy implementation Type invariant UCN T&B - PBA/CodeContract-Intro
Representation invariant Implementation in the class class Person: Iperson { [ContractInvariantMethod] private void ObjectInvariant() { Contract.Invariant(!name.Equals("“) && name!= null && weight >= 0); } private String name; private int weight; public Person(String n) { Contract.Requires(n != null && !n.Equals("")); Contract.Ensures(n.Equals(name) && weight == 0); name = n; weight = 0; } Constructor must establish the invariant public override String ToString() { Contract.Ensures(Contract.Result<string>()!= null); return "Person(\"" + name + "\"," + weight + ")"; } public intGetWeight() { Contract.Ensures(Contract.Result<int>() == weight); return weight; } public void AddKgs(intkgs) { Contract.Ensures(weight == Contract.OldValue(weight) + kgs); weight = weight + kgs; } UCN T&B - PBA/CodeContract-Intro
interface as static type class as dynamic type static void Main(string[] args) { IPerson p = new Person("Kurt"); Console.WriteLine(p.ToString()); p.AddKgs(99); Console.WriteLine("GetWeight: "+p.GetWeight()); Console.WriteLine(p.ToString()); Console.ReadLine(); p.AddKgs(-9); Console.ReadLine(); Console.WriteLine(p.ToString()); IPerson pp = new Person(""); Console.WriteLine(pp.ToString()); Console.ReadLine(); } UCN T&B - PBA/CodeContract-Intro