2011-01-03 6 views
7

coders at workという本では、著者は "あなたのコードでどのように不変式を使うのですか"と尋ねます。この質問が意味することを説明してください。不変のアサーションはC#プログラミングに適していますか?

私はクラス不変式on wikiを見ましたが、この例はJavaであり、Javaではこの例をC#に関連付けるのに十分なほど熟練していません。 .NET 4.0では、不変性、共分散、反分散が導入され、よく説明されています。here.不変性は非常に広いです。作者の言葉の使用は単体テストに関連しているようです。本を読んでいる人には、著者はどういう意味ですか?単体テスト後の妥当性をテストすることを前提としていますか?

答えて

10

単語invariantは、特定の条件の下で何かが変更されないことを意味しません。不変量にはさまざまな種類があります。例えば、物理学では、光の速度はローレンツ変換の下で不変であり、すなわち、基準フレームに変更すると変化しない。プログラミングでは、多くの種類の不変量もあります。関数の寿命中に変化しないメソッドinvariants、オブジェクトの生涯にわたって変化しないクラス不変量があります。

クラス不変式は、常に公に観察可能なものですそのクラスのインスタンスで真。

これは、共変/逆分散には決して関係しません。共変/差異分散は、異なる(汎用)パラメータまたは戻り値の型を持つ他の型に代わることができる型を記述します。共変/逆変分をサポートしていないので不変なものを呼び出すことができますが、これはクラスやメソッドの不変量とはまったく異なる種類の不変量です。

  • データ:

    例えば、コレクションのいくつかの種類は以下の不変量を持っているかもしれません!= nullの

  • サイズ> = 0
  • 容量> = 0
  • サイズ< =キャパ

このクラスでは:

class MyCollection<T> 
{ 
    private T[] data; 
    private int size; 

    public MyCollection() 
    { 
    data=new T[4]; 
    } 

    public int Size{get{return size;}} 
    public int Capacity{get{return data.Length;}} 

    [ContractInvariantMethod] 
    protected void ClassInvariant() 
    { 
    Contract.Invariant(data != null); 
    Contract.Invariant(Size >= 0); 
    Contract.Invariant(Capacity >= 0); 
    Contract.Invariant(Size < Capacity); 
    } 
} 

ほぼすべてのクラスには、いくつかの不変条件ではなく、誰もが持っていますそれらを強制する。 .net 4は、コード契約を使用してそれらを文書化し、アサートする良い方法を追加します。

+1

.NETの不変性は他の種類の不変性には関係しません。私は同意しませんが、おそらくそれは私が間違っているところです。多分型不変性は、クラス不変性や単体テストの使用法とは無関係であり、初歩的なレベルにのみ関係していると考えられます。 「不変性」を単に「変化しない」と定義した場合。問題は「変化しないことをどうやってテストするのか」です。または、「有効な値の範囲をどのようにテストしますか」という質問ですか? –

+0

@ P.Brian不変量には多くの種類があります。そして、タイプの分散はクラス不変量とは完全に無関係です。私は入門の段落を追加しました。 – CodesInChaos

+0

@ P.Brian .net 4でクラス不変式を実行する方法を見るには、 "Lee"の答えを参照してください。これを行うと(適切なコンパイラ設定を選択すると)コードは書き換えられ、パブリックメソッドの終わりに不変条件をテストします。 – CodesInChaos

2

この場合、不変量は、パラメータに適用される条件を意味し、関数/メソッドの存続期間中は真のままです。 wikipediaから

:述語がシーケンスを開始する前に真であるならば、それはの終わりに当てはまります:コンピューター・サイエンスで

、述語が一連の操作に対して不変と呼ばれてはいることを提供しましたシーケンス。

.NETでは、不変量はCode Contractsを使用してチェック/強制できます。

+0

私は自分の質問を理解するために本を読む必要はないと思うが、著者が質問する方法は誰もがそうしているように「事実」または「どのようにこれらのものを使うか」である。私は意図的に不変量を任意の目的のために使用したことはありませんし、.NETでは、それらを考慮するには壁の属性から離れている必要があるようです。ですから、不変量の一般的な使用は過去のものか、アセンブリ/ C/C++に限定されていますか? –

+0

@ P.Brian.Mackey - 私はそれらを一度も使用していませんが、CSのバックグラウンドから来た人は、より正確な "正しさ"を得るためにそれを使用しようとしています。私は彼が誰もが不変量とその使い方を知っていると仮定していると思います。 – Oded

1

この文脈での意味は、C#4で導入されたジェネリック医薬品のコ・コントラバリエーションに関連するものではなく、あなたがリンクしているウィキペディアの記事と同じ意味です。 C#では、デバッグアサーション(つまりDebug.Assert(condition))とコードコントラクトライブラリを使用できます。クラス不変条件をアサートクラスのメソッドに適用することができるContractInvariantMethodAttributeは、例えばある:

[ContractInvariantMethod] 
protected void ClassInvariant() 
{ 
    Contract.Invariant(someCondition); 
} 
2

ウィキの例がよく、おそらく、非常に特異的であるJMLと不変量を実現エキゾチックであること研究技術を考えるが、それは主流では全く必要ではない。また、不変量について話すだけでなく、突然変異を主張することについて話すだけで、予想されることができました。これは、不変条件を考えるとき、私が考えるものではありません。私はCoders at Workを読んでいませんが、Coders at Workの誰かがJMLを使っているとは思っていません。

とにかく、私はいつも不変量が "早期にクラッシュする"素晴らしい方法であり、実際にプログラム状態が不合理な(計画外の)状態にあるときにあなたのコードが合理的なことをやろうとは思わないと考えました。

C#コードの不変式の良い例は、オブジェクトがその不変量を渡さない限り、オブジェクトを保存するためにN-Hibernateに決して与えないことです。データベースに入る。

  • あなたは常にプライマリ のメールアドレスプロパティを持つことになっ あるUserクラスがあるとし...私は、他の例を考えることができるかどうか見てみましょう、その後、保存する前に チェックに対して不変であるかもしれません に電子メールアドレスフィールドが空でないことを確認してください。 他のアプリケーションロジック のすべてのメールアドレスが存在すると仮定した場合 ユーザーにメールを後で送信すると、ユーザーが混乱する可能性があります。

  • さらに、ユーザオブジェクト メールオブジェクト「多くを持っている」と仮定し、 メールEmailクラス に、その後、所有ユーザーせずに不変を 存在するのはどんな意味がないという を想定 への電子メールの参照が常にnullでないことを確認することがあります。 電子メールの所有者を参照しようとすると、 がnullポインタ例外 となる孤立電子メールオブジェクトがあります。

  • あなたは は、従来の WPFフォームでのAmazon S3オブジェクトの状態 を提示することになっているGUIを書いているとします。 の不変式は、フォーム がオブジェクト に正しくバインドされていることを確認してから、そのフォームのイベントハンドラ を実行することがあります。

  • あなたがStackOverflowを書いているとします。 ここでの不変量は、ユーザーの評判レベルが負でないことを確認することです(ユーザーが評判のペナルティを受けている場合は )。 ネガティブな評判によって、 として経験をレンダリングするかわいらしいグラフが に壊れてしまうことがあります(これらのグラフは の0 Y軸の下にグラフを作成する場合を除いて、 )。

インバリアントがいつチェックされるかは、データ状態を変更するメソッドの最後に行うことができます。最も積極的かつ妄想的な防衛プログラミングのレベルでは、すべての方法の前後で不変量をチェックすることができます。

関連する問題