回答:
Collection<T>
はカスタマイズ可能なラッパーIList<T>
です。一方でIList<T>
密封されていない、それはどんなカスタマイズポイントを提供していません。Collection<T>
のメソッドはデフォルトで標準IList<T>
メソッドに委譲されていますが、簡単にオーバーライドして必要な処理を実行できます。内部でイベントを関連付けることも可能です。Collection<T>
IListで実行できるとは思えないます。
要するに、事実の後でそれを拡張する方がはるかに簡単であり、それは潜在的にはるかに少ないリファクタリングを意味するかもしれません。
IList
、IList<T>
、List<T>
など要するに、あなたはそれが呼び出されるかどうかはわかりません。ポリモーフィズムはこれを修正します。
ObservableCollection<T>
変更について通知するためにメソッドがオーバーライドされる例として、回答を追加することができます。
C#には、オブジェクトのバッグを表すための3つの概念があります。機能の増加順に、次のとおりです。
Enumerableには順序がありません。セットからアイテムを追加または削除することはできません。セット内のアイテムの数を取得することもできません。これにより、セット内の各アイテムに順番にアクセスできます。
コレクションは変更可能なセットです。セットにオブジェクトを追加および削除できます。また、セット内のアイテムの数を取得できます。しかし、まだ順序はありません。順序がないためです。インデックスでアイテムにアクセスする方法も、並べ替える方法もありません。
リストは、順序付けられたオブジェクトのセットです。リストの並べ替え、インデックスによるアイテムへのアクセス、インデックスによるアイテムの削除を行うことができます。
実際、これらのインターフェースを見ると、相互に構築されています。
interface IEnumerable<T>
GetEnumeration<T>
interface ICollection<T> : IEnumerable<T>
Add
Remove
Clear
Count
interface IList<T> = ICollection<T>
Insert
IndexOf
RemoveAt
変数またはメソッドパラメータを宣言するときは、
概念的には、一連のオブジェクトを処理する必要があります。
リスト内のすべてのオブジェクトに対して何かを実行できるようにする必要がある場合、必要なものはIEnumerable
次のとおりです。
void SaveEveryUser(IEnumerable<User> users)
{
for User u in users
...
}
あなたは、ユーザーがに保管されている場合は気にしないList<T>
、Collection<T>
、Array<T>
または何か他のもの。必要なのはIEnumerable<T>
インターフェースだけです。
セット内のアイテムを追加、削除、またはカウントできるようにする必要がある場合は、コレクションを使用します。
ICollection<User> users = new Collection<User>();
users.Add(new User());
ソート順を気にし、正しい順序にする必要がある場合は、リストを使用します。
IList<User> users = FetchUsers(db);
グラフ形式:
| Feature | IEnumerable<T> | ICollection<T> | IList<T> |
|------------------------|----------------|----------------|----------|
| Enumerating items | X | X | X |
| | | | |
| Adding items | | X | X |
| Removing items | | X | X |
| Count of items | | X | X |
| | | | |
| Accessing by index | | | X |
| Removing by indexx | | | X |
| Getting index of item | | | X |
これらのインタフェースを実装する2つのクラスがあります。しかし、それらは唯一のクラスではありません:List<T>
Collection<T>
System.Collections.Generic
ConcurrentBag<T>
注文されたオブジェクトのバッグです(IEnumerable<T>
)LinkedList<T>
インデックス(ICollection
)でアイテムにアクセスできないバッグです。ただし、コレクションにアイテムを任意に追加および削除できますSynchronizedCollection<T>
順序付けられたコレクションで、インデックスによってアイテムを追加/削除できますしたがって、簡単に変更できます。
IEnumerable<User> users = new SynchronizedCollection<User>();
SaveEveryUser(users);
必要な概念を選択してから、一致するクラスを使用します。
ICollection<T>
ていIList<T>
ます。具象実装が異なると、動作が異なる場合があります。たとえばList<T>
、IEnumerable<T>
インターフェースを介してにアクセスする場合、リスト内のアイテムを追加、削除、並べ替え、またはカウントする方法はありません。
List<T>
アプリケーションコード内での内部使用を目的としています。受け入れるまたは返すパブリックAPIの記述は避けてくださいList<T>
(代わりにスーパークラスまたはコレクションインターフェイスの使用を検討してください)。
Collection<T>
カスタムコレクションの基本クラスを提供します(直接使用できます)。
必要Collection<T>
な特定の機能がない限り、コードでの使用を検討してくださいList<T>
。
上記は単なる推奨事項です。
[改訂:フレームワーク設計ガイドライン、第2版]
Dictionary<string, List<string>>
List<string>
List<T>
それは(のような便利なメソッドの多くで非常に汎用性の高いそうですので、非常によく見られるコンテナであるSort
、Find
など、) -しかし、あなたは(たとえば、挿入上の項目を確認してください)動作のいずれかを上書きしたい場合は何の拡張ポイントを持っていません。
Collection<T>
はすべてのラッパーですIList<T>
(デフォルトはList<T>
)-拡張ポイント(virtual
メソッド)がありますが、などのサポートメソッドほど多くはありませんFind
。間接的なため、は少し遅いですがList<T>
、それほどではありません。
LINQ、中にメソッドを追加したList<T>
あまり重要になって、LINQツーオブジェクトは、とにかくそれらを提供する傾向があるため...例えばFirst(pred)
、OrderBy(...)
など
リストはより高速です。
例えば
private void button1_Click(object sender, EventArgs e)
{
Collection<long> c = new Collection<long>();
Stopwatch s = new Stopwatch();
s.Start();
for (long i = 0; i <= 10000000; i++)
{
c.Add(i);
}
s.Stop();
MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString());
List<long> l = new List<long>();
Stopwatch s2 = new Stopwatch();
s2.Start();
for (long i = 0; i <= 10000000; i++)
{
l.Add(i);
}
s2.Stop();
MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString());
}
私のマシンでList<>
は、ほぼ2倍の速度です。
編集する
なぜ人々がこれに反対票を投じているのか理解できません。私の仕事用マシンと自宅用マシンの両方で、List <>コードは80%高速です。
これは大学院の質問の1つです。Tのコレクションは一種の抽象的です。デフォルトの実装があるかもしれませんが(私は.net / c#の人ではありません)、コレクションには追加、削除、反復などの基本的な操作があります。
Tのリストは、これらの操作に関するいくつかの詳細を示しています。追加には一定の時間がかかり、削除には要素の数に比例した時間がかかり、getfirstは一定の時間である必要があります。一般に、リストは一種のコレクションですが、コレクションは必ずしも一種のリストであるとは限りません。
Hanselman Speaks:「Collection<T>
リストのように見え、List<T>
内部にもあります。単一のメソッドList<T>
はすべて内部に委譲します。これは、を公開する保護されたプロパティを含みList<T>
ます。」
編集: Collection<T>
System.Generic.Collections .NET 3.5には存在しません。.NET 2.0から3.5に移行する場合、多くのCollection<T>
オブジェクトを使用している場合は、明らかなものがない限り、コードを変更する必要があります...
編集2:Collection<T>
.NET 3.5のSystem.Collections.ObjectModel名前空間に追加されました。ヘルプファイルはこれを言います:
「System.Collections.ObjectModel名前空間には、再利用可能なライブラリのオブジェクトモデルでコレクションとして使用できるクラスが含まれています。これらのクラスは、プロパティまたはメソッドがコレクションを返すときに使用します。」
これらのインターフェースはすべてから継承しているためIEnumerable
、理解しておく必要があります。そのインターフェイスでは、基本的にクラスをforeachステートメント(C#)で使用できます。
ICollection
リストしたインターフェースの中で最も基本的なものです。これは、をサポートする列挙可能なインターフェースでありCount
、それについてです。IList
それがすべてですICollection
が、アイテムの追加と削除、インデックスによるアイテムの取得などもサポートします。これは、「オブジェクトのリスト」で最もよく使用されるインターフェースです。IQueryable
LINQをサポートする列挙可能なインターフェースです。IQueryable
IListからを作成してLINQ to Objectsを使用できますがIQueryable
、LINQ to SQLおよびLINQ to EntitiesのSQLステートメントの遅延実行にも使用できます。IDictionary
一意のキーと値のマッピングであるという意味で、別の動物です。キーと値のペアを列挙できるという点でも列挙可能ですが、それ以外の場合は、リストした他の目的とは異なる目的を果たしますMSDNによれば、List(Of T).Addは「O(n)操作」(「容量」を超えた場合)であり、Collection(Of T).Addは常に「O(1)操作」です。リストが配列とリンクされたリストのコレクションを使用して実装されている場合、それは理解できるでしょう。ただし、その場合は、Collection(Of T).Itemが「O(n)操作」であると想定されます。しかし-それは- じゃない!?!Collection(Of T).Itemは、List(Of T).Itemと同様に「O(1)操作」です。
その上、上記の「tuinstoel」の「12月29日08:22:31」の投稿では、速度テストはList(Of T).AddがCollection(Of T).Addよりも高速であることを示していると主張しています。ロングとストリング。MSDNによると、私は彼の主張する80%に比べて33%速くなっただけですが、それは反対で「n」倍だったはずです!?!
どちらも同じインターフェースを実装しているため、同じように動作します。多分それらは内部で異なって実装されますが、これはテストする必要があります。
私が目にする唯一の実際の違いは、名前空間とCollection<T>
でマークされている事実です。そのComVisibleAttribute(false)
ため、COMコードはそれを使用できません。
他の質問に加えて、一般的なリストと収集機能の概要をまとめました。コレクションはリストの限られたサブセットです:
* = プレゼント
o = 部分的に存在
プロパティ/ メソッドコレクション< T > リスト< T > --------------------------------------- -------
Add() * *
AddRange() *
AsReadOnly() *
BinarySearch() *
Capacity *
Clear() * *
Contains() * *
ConvertAll() *
CopyTo() o *
Count * *
Equals() * *
Exists() *
Find() *
FindAll() *
FindIndex() *
FindLast() *
FindLastIndex() *
ForEach() *
GetEnumerator() * *
GetHashCode() * *
GetRange() *
GetType() * *
IndexOf() o *
Insert() * *
InsertRange() *
Item() * *
LastIndexOf() *
New() o *
ReferenceEquals() * *
Remove() * *
RemoveAll() *
RemoveAt() * *
RemoveRange() *
Reverse() *
Sort() *
ToArray() *
ToString() * *
TrimExcess() *
TrueForAll() *