以前InfoQは.NET向けのCode Contractsの可用性(参考記事・英語)について取り上げた。今回、 .NETへの重要な追加である、Code Contractsの使用に関するさらなる詳細を提供する。
.NET 4.0以前は、%PROGRAMFILES%/Microsoft/Contracts/PublicAssembliesの下にインストールされるライ ブラリ、Microsoft.Contracts.dllを参照することで、ContractsはVisual Studioプロジェクトに追加される。.NET 4.0は、mscorlib.dllにContractsを含む。ビルド時静的にもしくは実行時動的に実行されるように、妥当性確認を指定することができ る。複数の種類のcontractsがある。たとえば、Preconditions、Postconditions、Object Invariants、Assertions、Assumptions、 Quantifiers、Interface Contracts、Abstract Method Contractsである。
Contract.Requires()を使用して前提条件は、定義される。またシンボルCONTRACTS_FULLもしくは CONTRACTS_PRECONDITIONSが使用される場合、そのコンパイルの結果はILに表示される。一例は以下のとおりである。
Contract.Requires( x ! = null );
この前提条件は、以下の例にあるように一般的には、パラメータの妥当性確認がメソッドのボディに入った際に使用される。
public Rational( int numerator, int denominator) { Contract.Requires( denominator ! = 0 ); this .numerator = numerator; this .denominator = denominator; }
Contract.Requires()によって指定される条件が満たされない場合、Debug.Assert(偽)が呼び出され、それからEnvironment.FailFast()が呼び出される。アセンブリに前提条件が必要な場合、たとえどんなシンボルがコンパイル時に使用されようとも、Contract.RequiresAlways()が使用されるべきである。
メソッドが終了する場合、次の例にあるように、事後条件は満たされるcontractsであり、Contract.Ensures()で指定される。
public int Denominator { get { Contract.Ensures( Contract.Result() != 0 ); return this .denominator; } }
戻りの前に、条件が指定されると、実際戻り値の計算後に実行されるが、実行は呼び出し側に渡される。
オブジェクト不変条件は、クラスの各インターフェイスに対して指定される条件である。
[ContractInvariantMethod] protected void ObjectInvariant () { Contract. Invariant ( this .denominator ! = 0 ); }
その他のcontractsのタイプは、アサーションであるContractAssert() およびアサンプションであるContract.Assume()である。失敗中のAssers()は、Debug.Assert(偽)を呼び出す。アサン プションは、実行時のアサーションと類似しているが、静的な妥当性確認時は、異なる。アサンプションは、満たされることになっている条件を指定するために 使用されるが、その制限のためにコンパイラは妥当性確認をすることができない。
インターフェイス条件は、インターフェイスの条件を指定するために使用される。インターフェイスに関連付けられた個別のクラスを使用することで指定される が、インターフェイスメソッド宣言には、ボディがない。同様のことが抽象メソッドcontractsにも言える。
contractsを使用するクラスの例は、以下のとおりである。
役立つリンク:.NET向けのCode Contractsがダウンロードで利用可能(参考記事)、Code Contracts Download (MSI)(リンク)、Code Contractsオンラインドキュメンテーション(PDF)、Microsoft Research Code Contracts Webサイト(リンク)。
原文はこちらです:http://www.infoq.com/news/2009/02/Code-Contracts-Details