How to add an implementation to the contract code of an interface when inheriting an interface

My example is when interfaces that inherit the base interface must add message conditions that are the result of their additional fields. An example occurred when I decided to use the IInitialise interface as interfaces that inherit from this invariably desired pre / post condition added to the Initialize method.

I see that the problem is with abstract implementations that cannot escape each other (either due to interception, or using a rewriting device).

[ContractClass(typeof(IInitialiseContract))] public interface IInitialise { bool IsInitialised { get; } void Initialise(); } [ContractClassFor(typeof(IInitialise))] public abstract class IInitialiseContract : IInitialise { public bool IsInitialised { get { return default(bool); } } public void Initialise() { Contract.Ensures(IsInitialised == true); } } 

then later I end with the following interface

  [ContractClass(typeof(IEnginecontract))] public interface IEngine : IInitialise { ICommandManager CommandManager { get; } IDictionary<int, IEntity> World { get; } } [ContractClassFor(typeof(IEngine))] public abstract class IEnginecontract : IEngine { public ICommandManager CommandManager { get { Contract.Ensures(Contract.Result<ICommandManager>() != null); return default(ICommandManager); } } public IDictionary<int, IEntity> World { get { Contract.Ensures(Contract.Result<IDictionary<int, IEntity>>() != null); return default(IDictionary<int, IEntity>); } } public bool IsInitialised { get { return default(bool); } } public void Initialise() { // I would like to put my pre and post conditions here but // cannot because it is implemented in the base interfaces contract. } } 

I get here and I cannot find a good clean way to add conditions to Initialise ().

Edit2: If I put a request in this method, I would get an error similar to this

Warning 1 The IEngine contract class cannot define a contract for the IInitialise.Initialise method because its original definition is not of the IEngine type. Instead, define the contract as type IInitialise. IEngine.cs

Any ideas?

+4
source share
2 answers

I do not think that's possible. I often use code contracts, and as far as I can tell - I remember that I tried something like this - your derived interface interface code should include all the conditions again, it cannot inherit them.

+2
source

Any methods that are associated with an interface other than the one with which you are writing contracts should be marked abstract . The contracts for these methods will be inherited automatically, and you will not be able to change them (or this will change the meaning of the base interface, which makes no sense).

So, you should have your basic interface and its contracts:

 [ContractClass(typeof(IInitialiseContract))] public interface IInitialise { bool IsInitialised { get; } void Initialise(); } [ContractClassFor(typeof(IInitialise))] public abstract class IInitialiseContract : IInitialise { public bool IsInitialised { get { return default(bool); } } public void Initialise() { Contract.Ensures(IsInitialised == true); } } 

And your derived interface and its contracts (note the abstract inherited ones):

 [ContractClass(typeof(IEnginecontract))] public interface IEngine : IInitialise { ICommandManager CommandManager { get; } IDictionary<int, IEntity> World { get; } } [ContractClassFor(typeof(IEngine))] public abstract class IEnginecontract : IEngine { public ICommandManager CommandManager { get { Contract.Ensures(Contract.Result<ICommandManager>() != null); return default(ICommandManager); } } public IDictionary<int, IEntity> World { get { Contract.Ensures(Contract.Result<IDictionary<int, IEntity>>() != null); return default(IDictionary<int, IEntity>); } } public abstract bool IsInitialised {get;} public abstract void Initialise(); } 
+3
source

All Articles