Code Contracts の製品開発利用への展開が進んでいない。当初からあった数多くの技術的目標は今も有効だが,目前にある問題や障害のために,現在の形式での実現は遠からず断念せざるを得なくなる。
Code Contracts の最も基本的で重要な機能のひとつは null 参照の検出である。コンパイル時に null 参照例外の可能性を検出できるならば,開発者にとっての利益は大きなものだろう。残念ながら Code Contracts は,今にいたってもこれを実現できていない。
最も罪が大きいのは,フィールドの readonly 修飾子 (readonly modifier) を理解する能力を持っていないことである。フィールドがコンストラクタ以外からは変更できないことを示すこの修飾子は,開発者たちが .NET 1.0 の時代から C# や VB で利用しているものだ。また readonly 修飾子はインライン初期化式 (inline initializer) とペアで使用されることも多いが,これにはフィールドが null にならないことを検証可能な形で明確にするという目的がある。しかし残念なことに,Code Contract の静的チェッカは readonly 修飾子の解釈もフィールドへの値設定の検査も行わず,誤った警告を大量に出力する。
Visual Basic 開発者にとっては,静的チェッカが “If (aString = "")” というシンタックスを理解しないことも大きな問題だ。これは比較的新しい関数である “String.IsNullOrEmpty” と意味的には同一だが,VB コードの null 文字列チェックには慣用的にこの記法が用いられている。静的チェッカがこのような行を事実上無視するために,VB 開発者は,さらに多くの誤った警告に悩まされることになる。ただし Microsoft の Francesco Logozzo 氏によれば,次のリリースではこの対策が実施されるということだ。
同じように進展の見えない問題として,共通シナリオが属性を扱えない,というものがある。例えばオブジェクトを返す関数では,結果が null でないことを検証したい場合がよくあるが,それには次のような,いくぶん退屈なコードを書かなければならない。
Contract.Ensures(Contract.Result(OfSomeType)() IsNot Nothing)
Contract.Ensures(Contract.Result<SomeType>() !=null);
開発者が望んでいるのは,シンプルな属性を利用する方法だろう。
<NotNull()>PublicFunctionFoo() As SomeType
[NotNull] SomeType Foo()
Code Contracts はアセンブリの更新が可能なのだから,特定のパラメータに対して null を受け入れるかどうかなど,別の共通シナリオに変換する属性を追加するのは簡単なはずだ。さらには ArgumentNull あるいは ArgumentOutOfRange 例外を投げるような正しいコードの自動生成さえ可能だろう。
残念なことに Code Contracts チームは,Code Contracts を使用しないクライアントのサポートを要するコードベースに対して最初から対立関係にある。通常ならば ArgumentException を投げるようなエラーに対しても,例外ではなくアサーションを使用する,というように。当然だがこれは,まったく受け入れがたいものである。なぜなら,アサーションの失敗がリカバリの機会も与えずに,自動的にプログラムそのものをクラッシュさせてしまうからだ。
それ以来状況は好転することなく,逆に悪化の一途である。ランタイムチェックを有効にすると,“If check Then Throw” 形式で記述された引数チェックは事実上不可能になってしまう。
しかし Code Contracts チームが直面している本当の難問は,実は .NET フレームワーク自体のサイズに関するものだ。(すでに述べたような)静的チェッカの問題,あるいは 非 Code Contract のコードベースの処理に関する問題の解決に加えて,彼らは最初に立ち戻って .Net フレームワークの数限りないクラスに関する契約を定義しなければならない。
ただしこれらの問題の中で,十分な時間とリソースを持ってしても解決不能な問題はひとつもない。この強力だが複雑なツールを学ぶ時間と忍耐を持つものにとっては Code Contracts は将来,すべてのクラスのエラーを大幅に縮小あるいは完全に排除する,有望な技術であることに変わりない。