- Commenting Your Code
- Guarding Your Code
- Installing the Code Contracts Library
- Using Code Contracts
- Contracts on Interfaces and Abstract Methods
- Suppressing Warnings
- Building Contract Reference Assemblies
- Summary
Contracts on Interfaces and Abstract Methods
Interfaces are not allowed to contain method bodies. This means that their contracts must be written using a separate contract class. The contract class and its associated interface are linked using a pair of attributes. Listing 11 shows how to write contracts for an interface.
Listing 11Interface Contracts
[ContractClass(typeof(IFooContract))] interface IFoo { int Count { get; } void Put(int value); } [ContractClassFor(typeof(IFoo))] abstract class IFooContract : IFoo { int IFoo.Count { get { Contract.Ensures(0 <= Contract.Result<int>()); return default(int); } } void IFoo.Put(int value) { Contract.Requires(0 <= value); } }
Writing contracts for an abstract method in an abstract class is accomplished in the same way as interfaces, as shown in Listing 12.
Listing 12Contracts on Abstract Methods
[ContractClass(typeof(FooContract))] abstract class Foo { public abstract int Count { get; } public abstract void Put(int value); } [ContractClassFor(typeof(Foo))] abstract class FooContract : IFoo { public override int Count { get { Contract.Ensures(0 <= Contract.Result<int>()); return default(int); } } public override void Put(int value) { Contract.Requires(0 <= value); } }
In both cases, you needed to specify a dummy return value for the get accessor of the Count property. You actually need to do this for any property or method that has a return type other than void. The easiest way to do this is to always use default(T) for any type T.