2012-11-21 87 views
2

有沒有使用代碼合同來確保/檢查方法是否不會更改對象的任何成員的方法,類似於C++ const方法或將所有成員設置爲readonly確保對象不變?

即比以下更簡單的方法:使用Contract.EnsuresOnThrow

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)); 

或相同。

+0

可能重複的[C#:可以參數是不變的?](http://stackoverflow.com/questions/2339074/c-can-parameters-be-constant) – Sjoerd

+1

@Sjoerd我不認爲這是重複的,因爲這裏的操作是要求具體是否可以通過代碼合同完成。 – McGarnagle

+1

@Sjoerd:我不是問語言/編譯器是否可以執行這個檢查,我知道它不能。我問的是代碼合同靜態/運行時檢查可以做到這一點。 – ronag

回答

2

所以基本上你想檢查的方法是Pure。該official documentation表明其尚不支持(參見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. 
+0

也許你可以包括相應的爲了完成你的答案? – ronag

+0

@ronag - 對不起,好點。我已將文檔添加到答案中。 – Mightymuke

+0

大概「定義」==「定義」:) – porges

0

如果你的類實現

ICloneable 

IEquatable<YourClassType> 

的值相等(不引用平等),比你可以這樣寫:

Contract.Ensures( 
    this.Equals (Contract.OldValue ((YourClassType)this.Clone()) 
);