27

次のコードに出くわしました:

var collection = new Collection<string>();

Collection クラスがあまり使われているのを見たことがなく、その目的についての情報があまり見つかりません。.NET Framework のソースを見ると、List メンバー フィールドが格納されているため、List の単なるラッパーにすぎません。そのコンストラクタは次のとおりです。

public Collection()
{
  this.items = (IList<T>) new List<T>();
}

また、IList も実装しています。したがって、コレクションを次のように宣言できます。

IList<string> collection = new Collection<string>();

私にとっては、代わりにリストを作成することと機能的に同等です。

IList<string> collection = new List<string>();

では、独自のコードで List に対して使用したいのはいつでしょうか? 他の .NET コレクションの基本クラスであることはわかりますが、なぜこれを(内部および/または抽象ではなく) public 具象として含めるのでしょうか?


重複の可能性に関するコメントについて- 関連する質問への回答は、 Collection クラスが基本クラスとして使用されることになっていると言っているようです。私が本当に求めているのは、それが違うことです:

  1. 独自のコードで使用する場合は、代わりに List を基底クラスとして使用してみませんか?
  2. List の代わりに、独自のコードで新しい Collection をインスタンス化することは本当に理にかなっていますか?
  3. 基本クラスとして機能するためだけに提供されているのであれば、なぜ抽象化されないのでしょうか?
4

5 に答える 5

18

MSDNのドキュメント自体がすでに最も重要な側面を示していると思います(私が強調表示しています)。

Collectionクラスは、アイテムの追加と削除、コレクションのクリア、または既存のアイテムの値の設定時の動作カスタマイズするために使用できる保護されたメソッドを提供します。

実装者へのメモ

この基本クラスは、実装者がカスタムコレクションを簡単に作成できるようにするために提供されています。実装者は、独自の基本クラスを作成するのではなく、この基本クラスを拡張することをお勧めします。

[ypurの更新された質問の編集]

1.独自のコードで使用する場合は、代わりにListを基本クラスとして使用してみませんか?

Collection<T>いくつかの保護されたメソッドを提供するため、次のような動作を簡単に実行overrideし、独自のビジネスロジックを完全に登録できます。

  • ClearItems()
  • InsertItem()
  • RemoveItem()
  • SetItem()

List<T>それらを提供せず、動作をオーバーライドするための保護されたメソッドがほとんどないため、カスタマイズが難しくなります。

2.リストの代わりに独自のコードで新しいコレクションを初期化することは本当に意味がありますか?

いいえ、コレクションを初期化するためだけではありません。独自のロジックを実装するための基本クラスとして必要な場合に使用します。

これはあなた自身のビジネスニーズに依存します。日常の開発作業のほとんどすべての場合、既存の(および多数の)コレクションは、必要なものをすでに提供しているはずです。タイプセーフなコレクションとタイプされていないコレクション、スレッドセーフなコレクションなど、考えられるあらゆるものがあります。

それでも、ある日、コレクションタイプを実装して、その中のアイテムを追加/更新/削除する前に特定の検証チェックを実行したり、特定の方法でまばらにしか入力されていないリストの次のアイテムへの移動を処理したりする必要がある場合があります。 。あなたは顧客がどんな考えを持っているかもしれないかを決して知りません。

そのような場合は、独自のコレクションタイプを作成すると役立つ場合があります。

于 2012-08-22T09:28:41.110 に答える
9

Collection(T)クラスは、他のコレクション クラス全体の基本クラスです。Listクラスは速度を最適化するクラスであり、Collection クラスは拡張性を重視して設計されています。

のメンバーを見ると、クラスにはない追加の保護された仮想メソッド ( など) がCollection(T)含まれていることがわかります。InsertItemList(T)

実際、Collection クラスのインスタンスを作成しました。この型をメソッド シグネチャのパラメーターとしてのみ使用すると思いますが、メソッドをコレクションの実装と密接に結合しないようにするためです (可能な場合)。

質問に答えるには:

  1. Collection(T)そのクラスが他のコレクション型の基本クラスとして使用されることを意図しているため、基本クラスとして使用します。柔軟性が向上します (保護された仮想メソッドInsertItemおよびRemoveItemを参照SetItem) 。

  2. コレクションが必要な場合は、 List(T)速度が最適化されているため、クラスのインスタンスを使用します。

  3. 実は、なぜCollection(T) クラスを抽象化していないのか不思議です。

于 2012-08-22T09:27:10.877 に答える
7

クシシュトフ・ツワリナは次のように述べています。

•リストは拡張するようには設計されていません。つまり、メンバーをオーバーライドすることはできません。これは、たとえば、プロパティから List を返すオブジェクトは、コレクションが変更されたときに通知を受け取ることができないことを意味します。Collection を使用すると、SetItem 保護メンバーをオーバーライドして、新しいアイテムが追加されたとき、または既存のアイテムが変更されたときに「通知」を受け取ることができます。

•リストには、多くのシナリオに関係のない多くのメンバーが含まれています。List はパブリック オブジェクト モデルには「ビジー」すぎると言えます。ListView.Items プロパティが豊富な List を返すと想像してください。次に、実際の ListView.Items 戻り値の型を見てください。これははるかに単純で、Collection や ReadOnlyCollection に似ています。

このため、FxCop のルール CA1002 では、一般的なリストを公開せず、代わりにコレクションを使用するように指示しています。FxCop ルールと、リストではなくコレクションを返す理由については、このコード分析チームのブログ投稿も参照してください。

質問 1 と 2 については、上記を参照してください。質問 3 については、基本クラスとして機能するだけではありません。インスタンス化して戻り値の型としても使用できるはずなので、抽象的ではありません。

于 2012-08-24T07:13:56.303 に答える
4

私自身の質問に答えるのはあまり好きではありませんが、Q3 に関する限り、その理由は理解できると思います。Bas Paap's answer で参照されているこのリンクを見ながら、私はそれを手に入れました。

要するに、 Collection クラスが抽象ではない理由は、後でクラスから派生するオプションを自分自身に残したい場合があるためです。当面は、これを戻り値の型として使用して、直接インスタンス化できます。リンクは、これが当てはまるコード例を示しています。

質問で提起された問題に対処したと思われる他のすべての回答に賛成しました。

于 2012-08-24T19:00:27.613 に答える
0

列挙型インターフェイスは、コレクションに対して前方のみの反復を提供しますが、コレクションのサイズを決定したり、インデックスによってメンバーにアクセスしたり、検索したり、コレクションを変更したりするメカニズムを提供しません。このような機能のために、フレームワークは、、およびインターフェースを提供ICollectionIListますIDictionary

ICollection<T>中程度の機能(たとえば、Countプロパティ)を提供します。

IList<T>そしてそれらの非ジェネリックバージョンは最大の機能を提供します(インデックスによる「ランダム」アクセスを含む)。

これらのインターフェースのいずれかを実装する必要があることはめったにありません。ほとんどの場合、コレクションクラスを作成する必要がある場合は、代わりにサブクラスCollection<T>などを作成できます。

これがお役に立てば幸いです。

于 2012-08-22T09:42:23.070 に答える