2009-05-20 7 views
3

コレクションを扱うときにプロパティを使用する最良の方法は何か不思議です。コレクションを扱うときのプロパティの正しい使い方

たとえば、Fooクラスがあり、そのクラスのリストを保存したいとします。次のうちどれを使用する必要があります。

private List<Foo> myList; 
private List<Foo> myOtherList = new List<Foo>(); 

今プロパティ:

public List<Foo> ListOfFoo 
    { 
    get 
    { 
     return myList; 
    } 
    set 
    { 
     myList= new List<Foo>(value); 
    } 
    } 

またはSETだけの値にすべきですか?

public List<Foo> ListOfFoo 
    { 
    get 
    { 
     return myList; 
    } 
    set 
    { 
     myList= value; 
    } 
    } 
+0

なぜ外部からコレクションを設定する必要があるのですか? – peterchen

+0

このプロパティは、リスト内のFooオブジェクトのみのドラッグアンドドロップ機能を可能にするカスタムコントロールを実行しています。データベースのクエリを実行してオブジェクトのリストを取得する予定です。各コントロールは、同じリストまたは異なるリストを持つことができます。 – Billy

答えて

2

他方はちょうど(nullに設定されている)基準を宣言becuse、上記サンプルは、リストへの参照を宣言し

private List<Foo> myOtherList = new List<Foo>(); 

を選択し、基準に新しいリストリストとassignesを作成します。

あなたはそれが例えばmylistに割り当てられた後はmyListがリストに起こるすべての変更をrefelectないようにしたい場合は

public List<Foo> ListOfFoo 
    { 
    get { return myList; } 
    set { myList= new List<Foo>(value); } 
    } 

を選択します。

List<string> myFirstList = new List<string>(); 
myFirstList.Add("Hello"); 
myFirstList.Add("World"); 

List<string> mySecondList = new List<string>(myFirstList); 
// mySecondList now contains Hello & world 

myFirstList.Add("Boyo"); 
// myFrist List now contains Hello, world & Boyo 
// mySecondList still contains Hello & world 

選択

public List<Foo> ListOfFoo 
    { 
    get { return myList; } 
    set { myList= value; } 
    } 

あなたは両方の参照が、例えば同じオブジェクトを指すようにしたい

List<string> myFirstList = new List<string>(); 
myFirstList.Add("Hello"); 
myFirstList.Add("World"); 

List<string> mySecondList = myFirstList; 
// mySecondList now contains Hello & world 

myFirstList.Add("Boyo"); 
// myFrist List now contains Hello, world & Boyo 
// mySecondList "also" contains Hello, world & Boyo 

実際に、そこに1つのリストだけで、両方の私の最初のと同じリストに私の第二の点ので、「また」以上、引用符で囲まれています。一般

0

によって異なります。

最初のスタイルを使用するときは、通常は不要なリストのコピーを作成します。 .Net規約は、セッターがプロパティへの参照を割り当てることです。これが私が第二の選択肢に傾く理由です。

ただし、コピー操作を実行する予定がある場合、最初のオプションは探しているものです。

2

通常、List<T>のようなリッチタイプのプロパティを使用したくない場合(通常はCollection<T>を使用します)、コレクションタイプのプロパティは通常読み取り専用です。コレクション自体はClearAddなどであり、これで通常は十分である。例えば

class Foo 
{ 
    Collection<Bar> _bars = new Collection<Bar>(); 

    public Collection<Bar> Bars { get { return _bars; } } 
} 

これはまた、あなたがCollection<T>の子孫を実装し、InsertItemSetItemなどのメソッドをオーバーライドすることによって、コレクションへの変更を検証するために開いたまま。

+1

一般的なケースでは、リストを使用したくないかもしれませんが、そうすることは大丈夫です。たとえば、内部データオブジェクトがある場合などです。 –

+0

SIZ - 1は、まだ私は外に可能な最小のインターフェイスを使用したい(例えばのIList <>) – peterchen

+0

peterchen - コレクションはIListの実装を取ることができますIListを、およびコレクションよりも広い、より簡単に使用するためのインタフェースを持っていますコンストラクタとしてラップする。 IMHOコレクションにIList を使用する理由はありません。 –

0

、唯一のインタフェース(ICollectionを、IListのまたは類似の)、および読み取り専用それを作る公開:

private IList<Foo> m_list = new List<Foo>(); 
public IList<Foo> List {get { return m_list; } } 

利点を:あなたは、例えば、実装を変更することができますListからObservable Listに切り替えます。インターフェイスではなく具体的​​なタイプのメンバーをm_listにする必要があります。追加の機能を使用する。

設定可能な外部リストでは、いくつかの問題が発生します。しかし、いくつかの本が必要な場合があります。

  • データが外部で作成することができ、かつ潜在的に大規模で、かつ変更が頻繁に(例えば数十項目の何千もの)外部リストを間で共有されなければならない
  • 異なるインスタンス
0

クラスでIEnumerator-Interfaceを使用しないでください。セッターを使用する必要がある場合は、特定の方法を使用してください。

このようにして、実際のリスト実装も隠すことになります。

class FooBar : IEnumerator 
{ 
    private Collection<Foo> col; 

    public IEnumarator GetEnumerator() 
    { 
    return col.GetEnumerator(); 
    } 

    public void SetList(Collection col) 
    { 
    this.col= col; // you can also make this more general and convert the parameter so it fits your listimpl. 
    } 
} 

class Clazz 
{ 
    private void WhatEver(){ 
    FooBar foobar = new FooBar(); 
    ... 
    foreach(Foo f in foobar) 
    {...} 
    } 
} 
関連する問題