web-dev-qa-db-ja.com

別のクラスのClassCollectionを作成することは良い習慣ですか?

Carclassがあるとしましょう:

public class Car
{
    public string Engine { get; set; }
    public string Seat { get; set; }
    public string Tires { get; set; }
}

駐車場についてシステムを作成しているとしましょう。Carクラスをたくさん使用するので、CarCollectionクラスを作成します。追加のメソッドがいくつかある場合がありますFindCarByModelなど:

public class CarCollection
{
    public List<Car> Cars { get; set; }

    public Car FindCarByModel(string model)
    {
        // code here
        return new Car();
    }
}

クラスParkingLotを作成する場合、ベストプラクティスは何ですか?

オプション#1:

public class ParkingLot
{
    public List<Car> Cars { get; set; }
    //some other properties
}

オプション#2:

public class ParkingLot
{
    public CarCollection Cars { get; set; }
    //some other properties
}

別のClassCollectionClassを作成することは良い習慣ですか?

35
Luis

.NETのジェネリックスの前は、「型付き」コレクションを作成するのが一般的でした。そのため、グループ化する必要があるすべての型に対して_class CarCollection_などが必要になります。 Genericsが導入された.NET 2.0では、_List<T>_を作成できるため、CarCollectionなどを作成する手間を省く新しいクラス_List<Car>_が導入されました。

ほとんどの場合、あなたの目的には_List<T>_で十分であることがわかりますが、コレクションで特定の動作が必要になる場合があります。これが当てはまると思われる場合は、オプション:

  • _List<T>_をカプセル化するクラスを作成します。例:public class CarCollection { private List<Car> cars = new List<Car>(); public void Add(Car car) { this.cars.Add(car); }}
  • カスタムコレクションを作成する_public class CarCollection : CollectionBase<Car> {}_

カプセル化アプローチを採用する場合は、少なくとも次のように宣言するように列挙子を公開する必要があります。

_public class CarCollection : IEnumerable<Car>
{
    private List<Car> cars = new List<Car>();

    public IEnumerator<Car> GetEnumerator() { return this.cars.GetEnumerator(); }
}
_

そうしないと、コレクションに対してforeachを実行できません。

カスタムコレクションを作成する理由には、次のものがあります。

  • _IList<T>_または_ICollection<T>_のすべてのメソッドを完全に公開したくない
  • コレクションにアイテムを追加または削除するときに追加のアクションを実行したい

いい練習ですか?それは、whyに依存します。たとえば、上に挙げた理由の1つであれば、そうです。

マイクロソフトはかなり定期的にそれを行っています、ここにいくつかのかなり最近の例があります:

あなたのFindByメソッドについては、それらを拡張メソッドに入れて、車を含むすべてのコレクションに対して使用できるようにしたいと思います。

_public static class CarLookupQueries
{
    public static Car FindByLicencePlate(this IEnumerable<Car> source, string licencePlate)
    {
        return source.SingleOrDefault(c => c.LicencePlate == licencePlate);
    }

    ...
}
_

これにより、車を格納するクラスからコレクションへのクエリの懸念が分離されます。

40
Trevor Pilley

いいえ。XXXCollectionクラスの作成は、.NET 2.0でのジェネリックの登場により、かなり時代遅れになりました。実際、最近、人々がこれらのカスタム形式からデータを取得するために使用する、洗練されたCast<T>() LINQ拡張機能があります。

9
Jesse C. Slicer

他のアイテムのコレクションを保持するための特別なクラスを作成する唯一の理由は、IListまたは別のタイプのインスタンスからカプセル化/継承するだけではなく、それに何か価値のあるものを追加するときでなければならないと思いますコレクション。

たとえば、あなたのケースでは、偶数/不均等の駐車スペースに駐車された車のサブリストを返す関数を追加します...そしてそれでも...それは頻繁に再利用される場合に限られます。関数と1回だけ使用されますが、ポイントは何ですか? [〜#〜]キス[〜#〜]

さて、多くの並べ替え/検索メソッドを提供することを計画している場合は、そうです、これは、特別なコレクションクラスの中で属すべき場所なので、便利だと思います。これは、いくつかの「検索」クエリの複雑さや、並べ替え/検索メソッドで実行できることを「隠す」ための良い方法でもあります。

1
Jalayn