++C++; // 未確認飛行 C ブログ

http://ufcpp.net/

C# 7に向けて(9): Method Contracts

with one comment

今 issue ページができてて大きめのものはこれが最後のはず。Method Contracts。メソッドに対する「契約」。

結構長かった… 結局、全9回に。今後は、「週刊ブログ」程度でよくなるはず。きっと。

契約プログラミング

そもそも「contracts」とは何か的な話は、昔書いたスライド貼って済まそう。

(補足: このスライドでは非null制約を例に挙げて説明していますが、非null制約は契約でやるよりも、「非null参照型」を作る方がいいと思います。C# 7向けの提案の中にはこの「非null参照型」も含まれています。)

一応、.NET 4の頃から、ライブラリとツールでのサポートはありました。

また、研究的な位置づけのプロジェクトでは、C# に契約プログラミング機能を足したプログラミング言語(Spec#)もありました。

まあでも、C# が言語機能レベルでサポートしないと流行らないよね、きっと。という状態。

問題

.NET 4で契約がらみのクラス(Contract)が追加されてからも、実際のところ、このContractクラスを使ってくれたライブラリは少ないです。

どういう問題があるかというと例えば、

  • Contract. を付けないと行けなくていちいちめんどくさい
  • 契約の宣言場所がメソッド本体の中(本来、外に見せない内部実装にあたる場所)にある
    • 契約は外から見えるべき
  • ポスト プロセスが必要
    • Contract.Requires/Ensures を書いている場所では実際には何も起こらず、コンパイル結果のILをさらに書き替えてチェックを行う仕組みになってる
    • ドキュメントへの反映(「このメソッドはこういう契約を持っている」みたいなのを doc コメントに反映)もポスト プロセス
  • ソースコードの静的解析が結構重い
  • Visual Studio の上位エディション(確か、当初、Ultimate 限定?Premium でも行けたかも)が必要
    • ポスト プロセス、静的解析ともに

提案: C# 言語機能での契約

文法的には Spec# の頃とあんまり変わらないものになりそう。

requires (事前条件: 引数が満たすべき条件) や ensures (事後条件: 戻り値が見たすべき条件)の違反は fail-fast (エラー ログを残して即座にプログラム終了)にするようです。契約は、理想を言えばコンパイラーによって違反は全部コンパイル エラーにしてしまう方がいいものです(単に、技術的困難から実行時に残るだけ)。テストによって契約違反は取りきるべき(ちゃんと、呼び出し元がすべて責任をもって引数チェックしてからメソッドを呼ぶ)もの。なので、規定動作は例外すら出さず、強制終了。

一応、requires/ensures の後ろに else throw を付けて、この挙動を変える(例外を投げるだけにする)機能は検討されているようです。

あと、呼び出し元側で責任をもってチェックする必要があるということは、requires/ensures 句内では、メソッドよりもアクセス制限の強いメンバーの参照は禁止されるべきです。internal なメソッドの契約で private フィールドを参照したりはできません。

広告

Written by ufcpp

2015年2月11日 @ 19:30

カテゴリー: C#

Tagged with

コメント / トラックバック1件

Subscribe to comments with RSS.

  1. […] C# 7に向けて(9): Method Contracts […]


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。