コレクションを公開する方法は、ユーザーがそのコレクションとやり取りする方法によって異なります。
private readonly Collection<T> myCollection_ = new ...;
public Collection<T> MyCollection {
get { return this.myCollection_; }
}
この戦略:
1)ユーザーが追加し、オブジェクトのコレクションから項目を削除する場合は、単純なGET専用のコレクションプロパティは、元の質問から最高(オプション#1)でありますWindowsフォームおよびWPF ItemsControl
コントロールのItems
コレクションに使用されます。このコントロールでは、ユーザーがコントロールを表示したいアイテムを追加および削除します。これらのコントロールは、実際のコレクションを公開し、コールバックまたはイベントリスナーを使用してアイテムを追跡します。
WPFは、ItemsSource
プロパティ(ItemsControl
)(元の質問のオプション3)など、ユーザーがコントロールする項目のコレクションを表示できるように、いくつかの設定可能なコレクションを公開しています。しかし、これは一般的な使用例ではありません。
2)ユーザーは唯一のオブジェクトによって維持されるデータを読み込むことは、あなたは読み取り専用のコレクションを使用することができますされている場合、Quibblesomeが示唆したように:ReadOnlyCollection<T>
がのライブビューを提供
private readonly List<T> myPrivateCollection_ = new ...;
private ReadOnlyCollection<T> myPrivateCollectionView_;
public ReadOnlyCollection<T> MyCollection {
get {
if(this.myPrivateCollectionView_ == null) { /* lazily initialize view */ }
return this.myPrivateCollectionView_;
}
}
に留意されたいです。基本的なコレクションなので、一度ビューを作成するだけで済みます。
内部コレクションはIList<T>
を実装していない、またはあなたは、より高度なユーザーへのアクセスを制限したい場合は、代わりに列挙子を通じてコレクションへのアクセスをラップすることができた場合:
public IEnumerable<T> MyCollection {
get {
foreach(T item in this.myPrivateCollection_)
yield return item;
}
}
このアプローチは、実装が簡単ですまた、内部コレクションを公開することなく、すべてのメンバーへのアクセスを提供します。ただし、コレクションが変更された後にコレクションを列挙しようとすると、BCLコレクションクラスは例外をスローするため、コレクションは変更されないままにする必要があります。基になるコレクションが変更される可能性がある場合は、コレクションを安全に列挙する軽量ラッパーを作成するか、コレクションのコピーを返すことができます。
3)使用すると、配列ではなく、より高いレベルのコレクションを公開する必要がある場合は最後に、あなたはorginal質問から(オプション#2を変更するからユーザーを防ぐために、配列のコピーを返す必要があります):
private T[] myArray_;
public T[] GetMyArray() {
T[] copy = new T[this.myArray_.Length];
this.myArray_.CopyTo(copy, 0);
return copy;
// Note: if you are using LINQ, calling the 'ToArray()'
// extension method will create a copy for you.
}
ユーザがプロパティを変更したときにそのことを知ることができないため、基本配列をプロパティで公開しないでください。配列を変更できるようにするには、対応するSetMyArray(T[] array)
メソッドを追加、またはカスタムインデクサを使用することができ、次のいずれか
public T this[int index] {
get { return this.myArray_[index]; }
set {
// TODO: validate new value; raise change event; etc.
this.myArray_[index] = value;
}
}
が(もちろん、カスタムインデクサを実装することにより、あなたはBCLのクラスの作品を複製しますが:)
配列は非常にリソース集約的なオブジェクトのボクシングとボックス解除を引き起こすことに注意してください。 – Brettski
配列が強く型付けされている場合(int []、long []など)、要素にアクセスするとボクシングが発生しません。これは、オブジェクト[]を使用して値タイプ(つまり、オブジェクト[] a = new {1,2,3})を格納している場合にのみ発生します。 –
ああ、公正なポイント、あなたは私の提案を改善しました。良いですね! :) – Quibblesome