12

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

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

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

VS

public class Product
{
   public Collection<Image> Images{get; set;}
}
4

6 に答える 6

13

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

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

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

  • また、影響が少なく、互換性を損なう可能性のある変更を簡単に行うことができます。Collection<Image>おそらく後で、それをではなく、別のコレクション タイプにしたいと判断するでしょう。ImageCollection以前と同じメソッドを持つようにクラスを調整できますが、別のものから継承できます。そうすれば、クライアント コードが壊れる可能性は低くなります。

内部使用コードだけの場合、決定は必ずしも重要ではなく、「より単純な方が良い」と判断する場合があります。

私の頭に浮かんだ例は、ESRI の ArcGIS Server API です。API でカスタム コレクションを使用しています。また、主にこれらの理由から、API でカスタム コレクションを使用します。

于 2009-10-09T16:28:39.493 に答える
9

一般に、具体的なクラスの代わりにIEnumerable<T>ICollection<T>またはなどのインターフェイスの 1 つを公開することをお勧めします。IList<T>

これにより、内部 API を変更する際の柔軟性が大幅に向上します。 IEnumerable<T>特に、後で内部を変更して結果のストリーミングを可能にする可能性があるため、最も柔軟です。

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

于 2009-10-09T16:44:58.263 に答える
5

私は2番目のものに行きます。いずれにせよ、クライアント コードは Image タイプを認識している必要があります。

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

于 2009-10-09T16:26:15.693 に答える
5

私が考えることができる主な理由は、そのコレクション自体で動作する画像のコレクションに固有のメソッドが必要になる場合があるということです。次に、ImageCollection クラスを使用してこれらのメソッドを含めます。古典的なカプセル化。

また、余談ですが、実際にはそのコレクションのゲッターのみを公開し、実際のコレクションで読み取り専用のバッキング フィールドを初期化する必要があります。おそらく、コレクション全体を置き換えるのではなく、アイテムをコレクションに追加/削除してもらいたいと思うでしょう:

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

-オイシン

于 2009-10-09T16:29:16.843 に答える
1

内部を拡張可能にするために public ジェネリック プロパティを使用することを好みますが、private フィールドは実際の機能を備えたカスタム フィールドになります。

通常は次のようになります。

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; }
   }
}

また、カスタム コレクション クラスを別のクラス内にネストすることもよくあります。これにより、追加/削除中に親クラスのプライベート メンバーを変更できます。

于 2009-10-09T16:46:27.413 に答える
1

使用する唯一の理由Collection<T>は、基になるリストへのすべての変更を表示できる仮想メソッドのセットにフックする場合です。これにより、削除への対応、イベントの実装などの操作を行うことができます...

これらのコレクションの変更に応答したり監視したりすることに興味がない場合List<T>は、 a がより適切なタイプです。

于 2009-10-09T16:27:48.557 に答える