8

仕事中の本のコーダーで、著者は「コードで不変条件をどのように使用しますか」と尋ねます。この質問の意味を説明してください。

wikiでクラスの不変条件を見ましたが、例はJavaであり、この例をC#に関連付けるのに十分なJavaのスキルがありません。.NET 4.0では、不変性、共変性、反変性が導入されており、ここで詳しく説明されています。不変性はとても広いです。著者による単語の使用法は、単体テストに関連しているようです。その本を読んだ人にとって、著者はどういう意味ですか?仮定を立てて、単体テストの後に妥当性をテストすることについて話しているのでしょうか。

4

4 に答える 4

10

不変という言葉は、特定の条件下で何かが変わらないという意味ではありません。不変条件にはさまざまな種類があります。たとえば、物理学では、光速はローレンツ変換では不変です。つまり、参照フレームに変更しても光速は変化しません。プログラミングには多くの種類の不変条件もあります。オブジェクトの存続期間中に変更されないクラス不変条件、関数の存続期間中に変更されないメソッド不変条件などがあります。

クラス不変条件は、そのクラスのインスタンスで常に(少なくとも公的に観察可能な時間に)真であるものです。

これは、共分散/逆分散とはまったく関係ありません。Co- / Contra-varianceは、異なる(ジェネリック)パラメーターまたは戻りタイプを持つ他のタイプの代わりに使用できるタイプを記述します。Co- / Contra-varianceをサポートしていないため、不変と呼ぶことができますが、これはクラスまたはメソッドの不変とはまったく異なる種類の不変です。

たとえば、ある種のコレクションには次の不変条件が含まれる場合があります。

  • データ!= 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は、コードコントラクトを使用してそれらを文書化およびアサートするための優れた方法を追加します。

于 2011-01-03T16:33:41.583 に答える
2

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

ウィキペディアから:

コンピュータサイエンスでは、述語は一連の操作の不変条件と呼ばれます。ただし、シーケンスを開始する前に述語がtrueの場合、シーケンスの最後でtrueになります。

.NETでは、コードコントラクトを使用して不変条件をチェック/適用できます。

于 2011-01-03T15:25:48.263 に答える
2

Wikiのその例は、JMLを使用して不変条件を実装しています。これは、非常に具体的で、エキゾチックで、おそらくよく考えられた研究技術ですが、主流である必要はまったくありません。また、不変条件について話すだけでなく、ミューテーターを主張することについて話すだけでも、期待どおりの結果が得られました。これは、不変条件について考えるときに私が考えることではありません。私はCodersatWorkを読んだことがありませんが、CodersatWorkの誰もがJMLを使用したとは思えません。

とにかく、私は常に不変条件が「早期にクラッシュ」し、実際にはプログラムの状態が不合理な(計画外の)状態にあるときにコードが合理的なことを行おうとしないようにするための優れた方法だと思っていました。

C#コードの不変条件の良い例は、オブジェクトがその不変条件を渡さない限り、保存のためにN-Hibernateにオブジェクトを渡さないことです。その不変条件は、無意味なデータがデータベースに入るのを防ぐために多数あるはずです。他の例を考えられるかどうか見てみましょう...

  • 常にプライマリ電子メールアドレスプロパティを持つことになっているUserクラスがあるとします。次に、保存する前にチェックする不変条件は、電子メールアドレスフィールドが空でないことを確認することです。そうしないと、後でユーザーに電子メールを送信しようとしたときに、すべてのユーザーの電子メールアドレスが存在すると想定する他のアプリケーションロジックが混乱する可能性があります。

  • さらに、Userオブジェクトに「多数の」Eメールオブジェクトがあり、所有するユーザーなしでEメールが存在することは意味がないと仮定すると、Emailクラスの不変条件は、Eメールのその参照を確認することです。 userは常にnullではありません。そうでない場合、孤立したEメールオブジェクトがあり、Eメールの所有者を参照しようとするとnullポインター例外が発生する可能性があります。

  • AmazonS3オブジェクトのステータスを従来のWPF形式で表示することになっているGUIを作成しているとします。フォームの不変条件は、そのフォームでイベントハンドラーを実行する前に、フォームがそのオブジェクトに適切にバインドされていることを確認することです。

  • StackOverflowを作成しているとします。ここでの不変条件は、ユーザーがレピュテーションペナルティを受けている場合でも、ユーザーのレピュテーションレベルが決して負にならないようにすることです。否定的な評判は、時間の関数として経験をレンダリングするこれらのきれいなグラフを壊す可能性があります(それらのグラフが0 y軸の下の線をグラフ化するように準備されていない限り、それらは非常によくあるかもしれません...)。

不変条件をチェックするタイミングについては、データの状態を変更するメソッドの最後にこれを行うことができます。防御プログラミングの最も攻撃的で妄想的なレベルでは、すべてのメソッドの前後で不変条件をチェックできます。

于 2011-01-03T15:56:37.623 に答える
1

この文脈での意味は、C#4で導入されたジェネリックの共分散および逆分散とは関係ありませんが、リンク先のウィキペディアの記事と同じ意味です。C#では、これはデバッグアサーション(つまりDebug.Assert(condition))およびコードコントラクトライブラリである可能性があります。たとえば、ContractInvariantMethodAttributeクラスの不変条件をアサートするクラスのメソッドに適用できるものがあります。

[ContractInvariantMethod]
protected void ClassInvariant()
{
    Contract.Invariant(someCondition);
}
于 2011-01-03T15:34:02.917 に答える