資料合約,Data contracts,Code Contracts
一般驗證value的輸入輸出,我們可以用以下傳統的方式
public void Initialize(string name, int id)
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("name");
if (id < 0)
throw new ArgumentOutOfRangeException("id");
// Do some work here.
}
而今天要介紹的Code Contract,可以將以上的寫法改的更為優雅,且功能更為強大。
寫法如下:
public void Initialize(string name, int id)
{
Contract.Requires(!string.IsNullOrEmpty(name));
Contract.Requires(id > 0);
Contract.Ensures(Name == name);
Contract.Ensures(Id == id);
}
在開始使用之前要先安裝 Code Contracts
開啟專案屬性
Code Contracts => Perform Runtime Contract Checking Custom Rewriter Methods 打勾
這樣就設置完成了。
接下來就開始介紹基本的兩個驗證
-
preconditions - Contract.Requires()
-
在執行method程式碼之前做的驗證
-
-
postconditions - Contract.Ensures()
-
在method執行結束後,做的驗證
-
以下程式範例,我限制傳入的數字要大於0的數字,且輸出一定要是傳入值的平方。
static void Main(string[] args)
{
int value = SquareMath(0);
Console.WriteLine(value);
}
private static int SquareMath(int value)
{
// preconditions
Contract.Requires(value > 0);
// postconditions
Contract.Ensures(Contract.Result<int>() == value * value);
return value * value;
}
因為我傳入是0,所以以上面執行結果,我會得到一個錯誤訊息。
同理,如果我輸出不是 value * value,則一樣會跳出例外狀況。
知道Code Contracts的基本用法後,接下來就是要介紹如何針對interface 的 method做驗證,且所有實作該interface的類別,都有該驗證功能。
1.定義一個interface
2.新增一個abstract class 定義contract
3.使用ContractClassAttribute和 ContractClassForAttribute 將contract綁在一起
[ContractClass(typeof(MathContracts))]
public interface IMath
{
int SquareMath(int value);
}
[ContractClassFor(typeof(IMath))]
public abstract class MathContracts : IMath
{
public int SquareMath(int value)
{
// 確保傳入數字大於0
Contract.Requires(value > 0);
// 確保輸出結果為輸入的平方
Contract.Ensures(Contract.Result<int>() == value * value);
throw new NotImplementedException();
}
}
這樣所有實作IMath的類別,都有自動驗證的功能,如以下範例:
public class TestMath : IMath
{
public int SquareMath(int value)
{
return value * 2;
}
}
static void Main(string[] args)
{
TestMath tm = new TestMath();
int value = tm.SquareMath(50);
Console.WriteLine(value);
}
我故意將輸出結果不是輸入的平方,因為Contract的關係,會幫我做輸出驗證,拋出Exception
且使用Contract的程式碼,可以自動產生xml document
可參考:http://weblogs.asp.net/gunnarpeipman/enabling-xml-documentation-for-code-contracts
以上為Code Contract 的基本介紹,其實Code Contract的功能非常強大,也算是必學的知識之ㄧ阿。
參考:
http://www.codeproject.com/Articles/103779/Introducing-Code-Contracts
http://www.codeproject.com/Articles/104707/Introducing-Code-Contracts-Part
一天一分享,身體好健康。
該追究的不是過去的原因,而是現在的目的。