Pure属性が.NETのバージョン4で追加された。これはCode Contractsイニシアチブの一部である。その目的は、System.Diagnostics.Contracts名前空間内のPure属性/関数およびその他の属性/関数を使用して、.NETのBase Class Library (BCL)を通してクラスとメソッドを修飾することであった。
それが終わると、Code Contractsツールを使用して高度な分析とバグ検出を実行できる。しかし、Code Contractsプロジェクトは失敗した。これにはいくつかの理由があるが、より説得力のある理由は以下のとおりである。
- 構文は冗長。開発者が属性を使用したい場合には完全な行が必要となる。
- コントラクトはリフレクションを介して公開されていない。サードパーティ製ツールの可能性が排除されている。
- コントラクトがXMLドキュメントとして公開されていない。ドキュメントに自動的に含めることはできない。
- 何らかの理由でコントラクトに反した場合、アプリケーションはログに記録されることも修正措置を取ることもせずにすぐにクラッシュした。
- このツールは通常のコンパイルパスの外側にある。追加の手順が必要になり、そのためビルドサーバの使用がより困難になった。
Code Contractsプロジェクトが終了してからは、Roslynアナライザが静的解析ツールとして使われてきた。Roslynアナライザは通常のVB/C#コンパイラパイプラインの一部のため、それらを使用してもビルドプロセスが複雑になることはない。
MicrosoftのDan Moseley氏は、「コードコントラクト属性をどうするか」との疑問を残しており、「私達はそれらを使用も強制もせず、コントラクトのアノテーションを削除した。」と報告している。
Microsoftの別の従業員であるAndrew Arnott氏は、Pure属性は特に有用であるという考えに反対している。
しかし、[Pure]は、[Pure]メソッドが結果に対して何もせずに実行されたときに警告を出すアナライザを作成できるので便利である。
この背後にある基本的な考え方は、Pureとマークされているメソッドには決して副作用がないということである。その唯一の目的は値を返すことである。もし値を返し、その後その値が無視される場合、そもそもそのメソッドを呼び出す理由はない。したがって、警告は常に間違いを示している。
そしてそれが起こるべきことである。Microsoft.CodeQuality.Analyzersを使用している場合、ルールCA1806はPureメソッドの結果を無視することについて警告する。しかし、2つのキャッチがある。
第一に、メソッドが不適切にPureとマークされている場合は警告されない。その機能は理論的に可能である。それはPureメソッドは他のPureメソッドからのみ読み取るべきであるためである。
次に、コンパイラ定数 「CONTRACTS_FULL」を含める必要がある。Pure属性自体は、Conditional属性でマークされる。つまり、前述のコンパイラ定数がないと、Pure属性はコンパイル済みコードから削除される。これは実際には.NETのimmutableコレクションライブラリのいくつかのメソッドに起こった。
InfoQからの質問:最近の.NET開発で他にどのようなCode Contracts機能を知りたいか。