3

これが可能かどうかはわかりませんが、基本的には、プロパティを公開するReadOnlyCollection<ReadOnlyCollection<MyType>>クラス内の基になるコレクションを変更しながら、 type のプロパティを公開したいと考えています。さらに、クラスのユーザーが返されたコレクションへの参照を保持できるようにして、プロパティを公開するクラスで内部的に更新すると更新されるようにします。

たとえば、これが単一のコレクションである場合、次のようにすることができます。

  public class MyClass {
    private List<MyType> _List;
    public ReadOnlyCollection<MyType> RList {
      get {
        return _List.AsReadOnly();
      }
    }
  }

を実行することで、クラス内のリストにアイテムを追加することができ_List.Add()ます。さらに、このクラスのクライアントが行う場合は、次のように言います。

var collectionRef = myClassInstance.RList;

次にcollectionRef、要素をリストに追加すると、内部からも変更されMyClassます。

リストのリストが必要な場合、問題が発生します。

  private List<List<MyType>> _List;
    public ReadOnlyCollection<ReadOnlyCollection<MyType>> RList {
      get {
        return _List.AsReadOnly();
      }
    }

上記の試みの差し迫った問題はAsReadonly()、外側のリストにのみ適用されることです。ReadOnlyCollection<List<MyItem>>したがって、プロパティの宣言された型ではないa を返そうとします。宣言されたプロパティの型を満たすために私が考えることができる唯一の方法はReadOnlyCollection、次のような方法で新しいを作成することです。

new ReadOnlyCollection<ReadOnlyCollection<MyItem>>(_List)

また

new ReadOnlyCollection<ReadOnlyCollection<MyItem>>() {
new ReadOnlyCollection<MyItem>(_List[0]),
new ReadOnlyCollection<MyItem>(_List[1]),
...
}

しかし、このネストされたコレクションを作成するための構文がどうなるかはわかりません。また、「新しい」コレクションを作成することで、プロパティによって返される値への参照を使用して、基になるリストへの変更を追跡できないかどうかもわかりません。つまり、私が内部MyClassで行う場合_List[1].Add(myTypeInstance)、読み取り専用バージョンへの参照を保持している誰かがその新しいアイテムを見るかどうかはわかりません。

私は正直に言って、他のアプローチにもオープンです。基本的には、読み取り専用であるがプロパティを公開するクラス内で変更できる項目のリストのリストを公開するだけで済み、クライアントはプロパティ アクセサーから値を再度取得することなく反映された変更を確認できます。

4

2 に答える 2

0

ReadOnlyCollection少なくともそれ自体では、これを行うことはできません。に新しいリストを追加した場合_List、 のすべてのユーザーは、その新しいリストにリンクされた新しいリストRListを表示する機会を得る必要があります。単にそれをサポートしていません。元のアイテムの読み取り専用ビューのみであり、元のアイテムは変更可能です。ReadOnlyCollectionReadOnlyCollection

と同様に動作するカスタム クラスを実装できますがReadOnlyCollection、元のアイテムを返さずにラップする点が異なります。ReadOnlyCollectionの実装は簡単です: ほとんどすべてのReadOnlyCollectionのメソッドは 1 行で実装できます: 無条件の例外をスローする (例: IList.Add)、定数値を返す (例: IList.IsReadOnly)、またはプロキシされたコンテナーに転送する(例: ) のいずれかですCount

用途に合わせて変更する必要があるのは、アイテムを直接処理するさまざまなメソッドです。これは単なるインデクサー以上のものであることに注意してくださいthis[int]。同じリストの 2 つのプロキシが等しいものとして比較されることを確認し、プロキシから元のリストを取得するためのプライベート/内部メソッドを提供して、メソッドなどを機能させる必要もありますContainsGetEnumeratorが元のアイテムを返さないようにするために、カスタムの列挙型を作成する必要もあります。CopyToカスタム実装を作成する必要があります。しかし、これらのことを念頭に置いていても、それは非常に簡単なはずです.


とは言っても、おそらく多少クリーンではないが簡単なアプローチがあります。MyReadOnlyCollection<T>から派生したカスタム クラスを作成する場合ReadOnlyCollection<T>は、内部メンバー (の保護されたメンバーItemsに転送されます) を提供できます。ReadOnlyCollection<T>Items

次に、外部ユーザーもそれを呼び出すことができることを心配することなく、独自のアセンブリからMyReadOnlyCollection<MyReadOnlyCollection<MyClass>>および を作成できます。RList[0].Items.Add


前述のように、外側のリストが実際に変更されない場合は、より単純になる可能性があります。その場合、単純に次のようにすることができます。

public ReadOnlyCollection<ReadOnlyCollection<MyType>> RList {
  get {
    return _List.ConvertAll(list => list.AsReadOnly()).AsReadOnly();
  }
}

変更を監視する必要はありません_List

于 2014-07-05T23:10:48.913 に答える