1

Hi iam trying to put my code contract on interface on my class and i write something like this:

[ContractClass(typeof(MyClassContract))]
interface IMyClass
{
    int Id { get; set; }
}

[ContractClassFor(typeof(IMyClass))]
sealed class MyClassContract : IMyClass
{
    public int Id
    {
        get { return Id; }
        set { Contract.Requires(value > 0); }
    }
}

public class MyClass : IMyClass
{
    private int _id;
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

}

but don't like to be forced to define a get in contract that will be never used, mean that i can write it as

get { return "abcdrdkldbfldsk"; }

and don't like to be forced to use public property in an internal class only because cant write

get { return ImyClass.Id; } 

EDIT: this is what i would like to write:

[ContractClassFor(typeof(IMyClass))]
sealed class MyClassContract : IMyClass
{
    int IMyClass.Id
    {
        set { Contract.Requires(value > 0); }
    }
}
gt.guybrush
  • 1,320
  • 3
  • 19
  • 48
  • If the get will never be used, why not just declare `int Id { set; }` in the interface, and not implement it in `MyClassContract` nor in `MyClass`? – luiscubal Oct 10 '13 at 14:59
  • Well, if you're going to expose a get property in the first place, and the requirement is that an ID can never be smaller or equal to 0, than you also need to enforce this requirement on the getter. An interface doesn't enforce an implementation and therefore, a concrete class might very well use a different method other than the setter for setting the underlying value of the Id property – Polity Oct 10 '13 at 15:07
  • get will be use in MyClass, is the get in MyClassContract that will be never used – gt.guybrush Oct 11 '13 at 07:27
  • Polity, iam using contract only for class requirement at this time, not for declaring rule for resulting type. The only user input for MyClass is set and i MyClass only needs that this is correct. Putting a postcondition in get is only need to assure callers what myclass do but at this time iam not interested at this – gt.guybrush Oct 11 '13 at 07:32
  • 1
    Your set wil never be used either. As for a non void method, just end it with `throw new NotImplementedException();`. – Kris Vandermotten Oct 11 '13 at 07:42
  • ok, but no way for not writing it? Like the way i added to my question? – gt.guybrush Oct 11 '13 at 08:10
  • If you Require(id > 0) in the setter why not Ensure(Result() >0) in the getter? – Matthew Whited Jun 06 '15 at 11:02

1 Answers1

2

If you add a Contract invariant in the ContractClassFor (MyClassContract):

[ContractInvariantMethod]
private void ObjectInvariant ()
{
  Contract.Invariant (Id >= 0);
}

Then an Ensures / Requires pair will be added on the get / sets for the property. (Ref 2.3.1 of the reference)

You can then use an automatic property in the ContractClassFor

int Id { get; set; }

(i.e. will still need to add the property, because of the interface)

More here

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • ok, is something, but can't write Contract.Invariant (MyClass.Id >= 0) so i have to write it as public variable; and see no way to specify an exception type – gt.guybrush Oct 14 '13 at 14:39