.NET Framework 4.0 新功能:Code Contracts

MSDN Magazine 2009 年 8 月號CLR Inside Out 專欄主題是 .NET Framework 4.0 的新功能:Code Contracts,由 Melitta Andersen 執筆。正如其名稱所揭示的,這項新功能的目的即在於進一步支援合約式設計(design by contract)的概念。


我拿 Visual Studio 2010 Beta 版小試了一下,從下面這個簡單的程式片段,可約略看出 Code Contracts 的基本用法。
範例程式
1:  using System.Diagnostics.Contracts;
2:  
3:  namespace CodeContractDemo
4:  {
5:      class Program
6:      {
7:          static void PutInCart(string item, int price)
8:          {
9:              Contract.Requires(price > 0, "Price must > 0");
10:  
11:              Console.WriteLine(item);
12:          }
13:  
14:          static void Main(string[] args)
15:          {
16:              PutInCart("OOAD Book", -1);
17:          }
18:      }
19:  }

Code Contracts 包含一組工具和類別,而程式的「合約」,就是利用其中的 Contract 類別所提供的一些靜態方法來指定。就如範例程式的第 9 行,這裡是使用 Contract.Requires 方法來檢查傳入參數的值是否合法(參數 price 的值必須大於 0)。而第 16 行呼叫 PutInCart 時故意傳了 -1 進去,是為了方便我們觀察程式執行時會出現什麼狀況。
在預設的情況下,用 Visual Studio 2010 編譯和執行,你會發現程式的執行結果毫無異狀,也就是說,Contract.Requires 呼叫完全沒有作用。這是因為雖然 .NET 4 已經內建 Contract 類別(於 System.Diagnostics.Contracts 命名空間),但 Visual Studio 2010 還要安裝 Code Contracts 工具包,才能提供合約的檢查功能。

Code Contracts 開發工具包可由此處下載:http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx

安裝好 Code Contracts 工具包之後,在 Visual Studio 2010 中開啟專案選項,就會看到多出一項 Code Contracts 設定,參考下圖:


如果勾選 Runtime Checking,表示程式會在執行時檢查合約指定的條件。 如此一來,前面的範例程式在執行時便會出現如下圖的警告訊息:


如果勾選 Static Checking,則每當你 Build 專案時,Visual Studio 就會執行檢查合約的動作。檢查的結果是顯示在 Output 視窗裡:

三種合約類型

Code Contracts 類別庫提供的合約主要有三種,包括在 method 中使用的「先決條件」(preconditions)、「後置條件」(postconditions),以及合約效力涵蓋整個物件的「物件定性」(object invariants)1
先決條件指的是 method 要能正確執行所須之條件,後置條件是 method 執行完後必須符合的條件,而物件定性則是套用至整個物件的合約,亦即在任何時候、任何地方,物件的狀態都會符合的條件。
前面範例所使用的就是先決條件,至於另外兩種合約的用法,也許改天再寫吧,有興趣的朋友可參考 Melitta Andersen 的文章


註 1:用 Google 查了一下 object invariants,這個詞目前好像還沒有比較通用的譯法。由於 invariant 有恆常不變、固定的意思,所以我譯為「物件定性」。

4 則留言:

  1. 應該是VS2010 Beta"1"吧? beta2還沒出來呢!

    回覆刪除
  2. Hi tomexou,

    目前微軟官方網站開放下載的版本確實只到 VS2010 Beta1,但我用的版本是非公開的版本,而且確實是 Beta 2。

    Help > About 裡面顯示的版本號碼為:
    Version 10.0.20728.1 B2Rel

    回覆刪除
  3. 剛剛想到,我是單從版本號碼來判斷,難道...是我誤會了?

    回覆刪除
  4. 雖然確定不是 beta1 的版本,但我也不確定是否為 beta2....版本號碼的 b2rel 看起來是很像,但說不定是 pre-beta2 或 CTP 版。謹慎起見,還是先將文中的 beta2 字樣拿掉好了。Thanks :)

    回覆刪除

技術提供:Blogger.
回頂端⬆️