不変という言葉は、特定の条件下で何かが変わらないという意味ではありません。不変条件にはさまざまな種類があります。たとえば、物理学では、光速はローレンツ変換では不変です。つまり、参照フレームに変更しても光速は変化しません。プログラミングには多くの種類の不変条件もあります。オブジェクトの存続期間中に変更されないクラス不変条件、関数の存続期間中に変更されないメソッド不変条件などがあります。
クラス不変条件は、そのクラスのインスタンスで常に(少なくとも公的に観察可能な時間に)真であるものです。
これは、共分散/逆分散とはまったく関係ありません。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は、コードコントラクトを使用してそれらを文書化およびアサートするための優れた方法を追加します。