リスコフ置換の原則では、サブタイプがスーパータイプの契約を満たす必要があります。私の理解では、これはReadOnlyCollection<T>
リスコフに違反することを伴います。 ICollection<T>
のコントラクトはエクスポーズAdd
とRemove
操作を行いますが、読み取り専用サブタイプはこのコントラクトを満たしません。例えば、
IList<object> collection = new List<object>();
collection = new System.Collections.ObjectModel.ReadOnlyCollection<object>(collection);
collection.Add(new object());
-- not supported exception
不変のコレクションが必要であることは明らかです。それらをモデル化する .NET の方法に何か問題がありますか? それを行うためのより良い方法は何ですか? IEnumerable<T>
少なくとも不変に見える一方で、コレクションを公開するという良い仕事をします。ただし、セマンティクスは大きく異なります。これは主にIEnumerable
、状態を明示的に公開しないためです。
私の特定のケースでは、 FSMをサポートするために不変のDAGクラスを構築しようとしています。最初に/メソッドが明らかに必要ですが、すでに実行されている状態マシンを変更できるようにしたくありません。DAG の不変表現と可変表現の類似性を表現するのに苦労しています。AddNode
AddEdge
現在、私の設計では、前もって DAG Builder を使用してから、不変グラフを一度作成する必要があります。その時点で、それは編集できなくなります。Builder と具体的な不変 DAG の間の唯一の共通インターフェイスはAccept(IVisitor visitor)
. おそらくより単純なオプションに直面して、これが過度に設計されている/抽象的すぎる可能性があることを懸念しています。同時に、NotSupportedException
クライアントが特定の実装を取得した場合にスローされる可能性のあるメソッドをグラフ インターフェイスに公開できることを受け入れるのに苦労しています。これを処理する正しい方法は何ですか?