パブリック メソッドのカスタム コレクションとジェネリック コレクション [終了]

StackOverflow https://stackoverflow.com/questions/1544800

質問

カスタム コレクションと汎用コレクションを公開するためのフレームワーク設計ガイドラインは何ですか?例えば

public class ImageCollection : Collection<Image>
{
     ...
}

public class Product
{
   public ImageCollection {get; set;}
}

VS

public class Product
{
   public Collection<Image> Images{get; set;}
}
役に立ちましたか?

解決

一般的に、そのような代わり具象クラスのIEnumerable<T>ICollection<T>又はIList<T>として、インターフェースのいずれかを露出することをお勧めします。

これはあなたの内部APIを変更するという点ではるかに柔軟性を備えています。 IEnumerable<T>は、特に、あなたが潜在的な結果のストリーミングを可能にし、後であなたの内部を変更することができますので、最も柔軟性があります。

あなたが「コレクション」の予想される使用パターンを知っている場合は、あなたが将来的にあなたに少なくとも制約を提供し、適切なAPIを公開する必要があります。たとえば、あなたは、人々はあなたが後で任意のコレクションに変更することができるようにだけ、あなたの結果を反復IEnumerable<T>を公開する必要がある、あるいは単に直接利回りリターンを使用するように切り替えることがわかっている場合。

他のヒント

パブリック API を構築している場合は、次の利点があるカスタム コレクションの使用を検討してください。

  • 拡張性 - API を変更せずに、将来的にカスタム コレクションに機能を追加できます。

  • 下位互換性 - クライアントがコレクションに対してプログラムした既存のコードを壊すことなく、コレクション クラスの内部を自由に変更できます。

  • また、影響を少なくしながら、破壊的な変更を行うことも容易になります。おそらく後で、それは望まないと判断するでしょう。 Collection<Image>, ただし、コレクションの種類は異なります - カスタマイズできます。 ImageCollection クラスは以前と同じメソッドを持ちますが、別のものを継承します。これにより、クライアント コードが壊れる可能性が低くなります。

内部使用のコードのみの場合、決定は必ずしも重要ではないため、「シンプルであるほど良い」を採用することもできます。

私の頭の中にある例としては、ESRI の ArcGIS Server API があります。これらは、API でカスタム コレクションを使用しています。また、主に次の理由から、API でカスタム コレクションを使用します。

私は、第1のために行くだろう。クライアントコードは、とにかく画像の種類を知る必要があります。

最初のものは、より多くのコードを意味する。

私は考えることができる主な理由は、あなたがそのコレクション自体を操作するイメージのコレクションに特有のいくつかのメソッドを持っている場合がありますということです。それから私は、これらのメソッドを含むようにImageCollectionクラスを使用します。クラシックカプセルます。

また、ちょうどさておき、あなたは本当にのみ、そのコレクションのgetterを公開し、実際のコレクションを読み取り専用バッキングフィールドを初期化する必要があります。おそらく、人々が追加/コレクションに項目を削除する、全体の事を交換しない:

class Product {
    private readonly Collection<Image> _images;
    public Product() { _images = new Collection<Image>(); }
    public Collection<Image> Images { get { return _images; } }
}

-Oisin

あなたが根底にあるリストに変異のすべてを見ることができる仮想メソッドのセットにフックしたい場合は、

これまでCollection<T>を使用する唯一の理由です。これはあなたが削除に応じるなどの操作を行うことができ、イベントを実装、など...

あなたが応答またはこれらのコレクションの変更を見て興味を持っていない場合は、

そしてList<T>は、より適切な型です。

私は内部を拡張可能にするために、公共の一般的な性質を持っていることを好むが、プライベートフィールドは、実際の機能を持つカスタム1になります。

これは通常、次のようになります:

public interface IProduct
{
     ICollection<Image> Images { get; }
}

public class Product : IProduct
{
   private class ImageCollection : Collection<Image>
   {
      // override InsertItem, RemoveItem, etc.
   }

   private readonly ImageCollection _images;
   public ICollection<Image> Images
   {
      get { return _images; }
   }
}

私はまた、多くの場合、私が追加/削除時に親クラスのいくつかの民間メンバーを変更することができます別のクラス内にネストされたカスタム・コレクション・クラスを作ります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top