2

Is there any way using Code Contracts to ensure/check that a method does not change any members of an object, similarly to C++ const methods or setting all the members to readonly?

i.e. a simpler way than the following:

Contract.Ensures(this.member1 == Contract.OldValue(this.member1));
Contract.Ensures(this.member2 == Contract.OldValue(this.member2));
Contract.Ensures(this.member3 == Contract.OldValue(this.member3));
Contract.Ensures(this.member4 == Contract.OldValue(this.member4));
Contract.Ensures(this.member5 == Contract.OldValue(this.member5));

or the same using Contract.EnsuresOnThrow.

ronag
  • 49,529
  • 25
  • 126
  • 221
  • possible duplicate of [C#: Can parameters be constant?](http://stackoverflow.com/questions/2339074/c-can-parameters-be-constant) – Sjoerd Nov 21 '12 at 09:45
  • 1
    @Sjoerd I don't think this is a duplicate, since the Op here is asking specifically if it can be done with code contracts. – McGarnagle Nov 21 '12 at 09:47
  • 1
    @Sjoerd: I am not asking whether language/compiler can perform this check, which I know it cannot. I am asking whether the code contracts static/runtime check can do this. – ronag Nov 21 '12 at 09:49

2 Answers2

2

So essentially you want to check that the method is Pure. The official documentation indicates that its not yet supported (see section 5.4):

5.4 Purity

All methods called within a contract must be pure: that is, they must not update
any pre-existing state. (A pure method is allowed to modify objects that have been
created after entry into the pure method.) Code Contract tools currently assume
the following things are pure:

* Methods marked [Pure] (If a type is marked [Pure], then that applies to all of
  its methods.) The pure attribute is dened in the contract library. (Section 4.3)

* Property getters.

* Operators (static methods whose names start with op , have one or two parameters
  and a non-void return type).

* Any method whose fully qualified name begins with
  System.Diagnostics.Contracts.Contract, System.String, System.IO.Path, or
  System.Type.

* Any invoked delegate, provided that the delegate type itself is attributed with
  [Pure]. The existing delegate types System.Predicate<T> and System.Comparison<T>
  are considered pure.

In the future, there will be a purity checker that will enforce these assumptions.
Mightymuke
  • 5,094
  • 2
  • 31
  • 42
0

If your class implements

ICloneable

and

IEquatable<YourClassType>

as value equality (not reference equality), than you can write:

Contract.Ensures( 
    this.Equals ( Contract.OldValue ( (YourClassType)this.Clone() )
);
ddur
  • 75
  • 3