代碼契約組件是對NET的重要補充這次我們將提供更為詳細的內容
如果要在NET 發布之前使用代碼契約我們可以在Visual Studio項目中引用程序集MicrosoftContractsdll該程序集安裝在%PROGRAMFILES%/Microsoft/Contracts/PublicAssemblies目錄下NET 會在mscorlibdll中包含契約組件我們可以指定契約驗證可在編譯時(靜態)或在運行時(動態)執行校驗
契約包含幾種類型前置條件(Preconditions)後置條件(Postconditions)對象不變量(Object Invariants)斷言(Assertions)假定(Assumptions)量詞(Quantifiers)接口契約(Interface Contracts)和抽象方法契約(Abstract Method Contracts)
前置條件使用ContractRequires()進行定義如果在編譯時使用了符號(Symbol)CONTRACTS_FULL或CONTRACTS_PRECONDITIONS那麼IL中就會包含其編譯結果例如
Contract
Requires( x ! = null )
如下所示前置條件通常作為方法體中的參數驗證如下所示
public Rational( int numerator
int denominator)
{ Contract
Requires( denominator ! =
);
this
numerator = numerator;
this
denominator = denominator;
}
如果不符合ContractRequires()指定的條件就會調用DebugAssert(false)然後調用EnvironmentFailFast()如果不管在編譯時使用哪個符號您都希望程序集中包含前置條件那麼可以使用ContractRequiresAlways()
當方法結束時後置條件表示其結果需要滿足的契約它通過ContractEnsures()方法指定如下例所示
public int Denominator {
get {
Contract
Ensures( Contract
Result() !=
);
return this
denominator;
}
}
雖然似乎在返回結果之前就指定了條件實際它還是會在返回結果之後調用者得到結果之前進行驗證
對象不變量則為每個實例指定條件
ContractInvariantMethod]protected void ObjectInvariant () {
Contract
Invariant ( this
denominator ! =
);
}
至於其他類型的契約斷言表示為ContractAssert()假定則表示為ContractAssume()一個失敗的Assert()會調用DebugAssert(false)假定與運行時斷言相似不同之處在於靜態檢驗的方式假定用於指定期望應該符合的條件而由於某些限制該條件無法得到編譯器的驗證
接口契約為接口指定條件它們使用在關聯於接口的獨立類上因為接口方法只能聲明而不能擁有方法體對於抽象方法契約同樣如此
以下為一個使用契約的類
From:http://tw.wingwit.com/Article/program/net/201311/15397.html