2011-01-31 48 views
4

我有這樣的代碼:CodeContract認爲分配readonly字段可以爲空

public class CodeContractSample 
{ 
    private readonly List<object> _items = new List<object>(); 

    public IEnumerable<object> Query() 
    { 
     Contract.Ensures(Contract.Result<IEnumerable<object>>() != null); 
     //if (_items == null) throw new Exception(); 
     return _items; 
    } 
} 

CodeContracts給出了這樣的警告:

CodeContracts:確保未經證實!Contract.Result>()= NULL

如果我取消註釋中間行,它會停止抱怨。但爲什麼它開始抱怨? _items不應該是空的..?

回答

5

合同不是100%,它的理解依然存在差距。

你說得對:結果沒有理由未經證實。有關此特定問題的更多信息,請參閱http://social.msdn.microsoft.com/Forums/en-US/codecontracts/thread/f82aa25c-e858-4809-bc21-0a08de260bf1

現在,你使用可以解決這個問題:

Contract.Assume(_items != null); 

您也可以做到這一點使用合同不變:

[ContractInvariantMethod] 
void Invariants() 
{ 
    Contract.Invariant(_items != null); 
} 
+0

不錯,這在我的單元測試中有一些斷言後也很有用...... :) – Allrameest 2011-01-31 15:16:40

-1

Contract.Ensures行承諾該方法永遠不會返回null。但是代碼中沒有任何東西可以阻止這種情況發生,直到您取消註釋該行。

+0

...除了`_items`在類的構造函數中初始化,`Query`是一個非靜態方法。 – fearofawhackplanet 2011-01-31 14:48:22

+0

我不認爲這種功能已經實現。這將需要對c#語言進行更改。請參閱http://channel9.msdn.com/Forums/TechOff/494357-Design-by-Contract-in-C/0ef9306b38314b1aa4c09deb0009144e – 2011-01-31 14:54:56

0

爲什麼你認爲物品永遠不會爲空?您可以在該類中使用另一種方法,將其設置爲空...

+3

它是隻讀的。只有構造函數可以將其設置爲null。但我沒有任何構造函數。 – Allrameest 2011-01-31 14:58:31

0

其實我能想象這樣的:

CodeContractSample s = new CodeContractSample(); 
s.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(s, null); 
var q = s.Query(); 

什麼你認爲 ?

相關問題