2

If I have an interface A and interface B that extends A, can I create a contract class BContract that inherits AContract?

If I try this, I get the following warning:

(1,1): warning CC1066: CodeContracts: Class 'BContract' is annotated as being the contract for the interface 'B' and cannot have an explicit base class other than System.Object.

I haven't tested this yet, but I assume that the implementation of the A interface in BContract is ignored, and the contracts specified in AContract take precedence - in other words I can stub out all methods and properties from A.

I appreciate that it's not a massive inconvenience to do this, but it does seem to lack clarity for anyone looking at BContract. It would save time, space and understanding to be able to derive BContract from AContract, so why is this not supported?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Andy
  • 3,596
  • 8
  • 34
  • 33
  • 1
    The following question looks similar to what you are asking. Maybe its answer will help you. http://stackoverflow.com/questions/3197797/code-contracts-how-to-deal-with-inherited-interfaces – irritate Feb 21 '11 at 14:12
  • hum yes that does look very close to what I was asking thanks! I think i'll keep this one up for a bit longer, because i'm asking why we can't inherit contract classes, not why the warning occurs in the first place. Not sure... feel free to disagree :) – Andy Feb 21 '11 at 14:38
  • If you've found an answer to your own question, it would be helpful if you put it into an answer, rather than editing the question, so we can upvote it and you can mark it as accepted. – Andrew Aylett Feb 22 '11 at 10:54

2 Answers2

2

Here's my guess (which I should have thought of before posting) - If interface B extended multiple interfaces - say A and C, with attendant contract classes AContract and CContract - which contract class should BContract inherit from?

There's less ambiguity in always stubbing out base interfaces, rather than mixing up stubs and inheritance of contract classes.

Andy
  • 3,596
  • 8
  • 34
  • 33
1

It is supported, but not in the way you're thinking: if interface B derives from interface A, then all the contracts defined on A are also automatically defined for B.

Edit: Here's an example for the comment;

[ContractClass(typeof(IAContracts))]
interface IA
{
    void Foo(int x);
}

[ContractClass(typeof(IBContracts))]
interface IB : IA
{
    void Bar(int y);
}

[ContractClassFor(typeof(IA))]
abstract class IAContracts : IA
{
    public void Foo(int x)
    {
        Contract.Requires(x >= 0);
    }
}

[ContractClassFor(typeof(IB))]
abstract class IBContracts : IB
{
    // inherited from IA
    public abstract void Foo(int x);

    // declared in IB
    public void Bar(int y)
    {
        Contract.Requires(y >= 0);
    }
}
porges
  • 30,133
  • 4
  • 83
  • 114
  • right... but if i want to create a contract for B - BContract, then I have to stub out all methods/properties from A. I was thinking it would be nice to inherit from AContract and avoid all that extra redundant code, which impacts readability. – Andy Feb 22 '11 at 10:27
  • Any inherited methods in BContract should be declared abstract. I'll update my question with an example. It's just the way C# classes work, they *have* to implement the methods of the interfaces they inherit from. – porges Feb 22 '11 at 20:23
  • of course. but if BContract could inherit AContract, which implements interface 'A' already, then BContract should not have to reimplement 'A'. But .net code contracts complains if BContract inherits from AContract, and my tiny brain took a while to work out why. – Andy Feb 24 '11 at 16:43
  • Ah, I see. I'm not sure of the rationale behind why they can't inherit directly. You could try asking the authors on the code contracts forum :) – porges Feb 25 '11 at 00:28