C#のさまざまなコレクションジェネリックインターフェイスの違い


11

しばらくの間、C#for WindowsおよびASP.net MVC開発で遊んでいます。しかし、私はまだいくつかの領域で不明です。私は、類似の種類のGeneric Collection Interfacesの使用と交換に関するパフォーマンスの問題の基本的な違いを理解しようとしています。

基本的な違いは何ですかIEnumerable<T>ICollection<T>List<T>(Class)

アプリケーションで問題が発生することなく、それらを使用および交換しているようです。また、これらの3つと交換できるこれらのような類似の汎用コレクションはありますか?


2
IList <T>もあります
jk。

回答:


19

List <T>はクラスであり、ICollection <T>およびIEnumerable <T>インターフェイスの両方を実装します。また、ICollection <T>はIEnumerable <T>インターフェイスを拡張します。少なくともすべての観点から、それらは互換性がありません。

List <T>がある場合、このオブジェクトがICollection <T>およびIEnumerable <T>インターフェイスで実装する必要があるメソッドとプロパティを実装することが保証されます。コンパイラはそれを認識しており、ICollection <T>またはIEnumerable <T>に暗黙的にキャストすることが許可されています。ただし、ICollection <T>がある場合は、List <T>か他の何か、おそらくDictionary <T>(TはKeyValuePair)かどうかをコードで明示的にチェックしてから、それをキャストする必要があります欲望。

ICollectionはIEnumerableを拡張しているので、IEnumerableにキャストできます。ただし、IEnumerableのみがある場合は、リストであることは保証されません。かもしれませんが、それは何か他のものである可能性があります。たとえばList <T>をDictionary <T>にキャストしようとすると、無効なキャスト例外が発生します。

したがって、それらは「交換可能」ではありません。

また、多くの汎用インターフェイスがあります。System.Collections.Generic名前空間にあるものを確認してください。

編集:コメントに関して、List <T>またはそれが実装するインターフェイスの1つを使用しても、パフォーマンスの低下はまったくありません。まだ新しいオブジェクトを作成する必要があります。次のコードを確認してください。

List<T> list = new List<T>();
ICollection<T> myColl = list;
IEnumerable<T> myEnum = list;

listmyColl、およびmyEnumはすべて同じオブジェクトを指します。リストとして宣言するか、ICollectionとして宣言するか、IEnumerableとして宣言するかにかかわらず、プログラムでリストを作成する必要があります。私はこれを書くことができました:

ICollection<T> myColl = new List<T>();

myColl、実行時にはまだリストです。

しかし、これは最も重要なポイントです... 結合を減らし、保守性高めるために、インターフェイスまたは抽象クラスまたは具象クラスに関係なく、可能な限り最小の分母を使用して変数とメソッドパラメーターを常に宣言する必要があります。

「PerformOperation」メソッドが必要とするのは、要素を列挙し、いくつかの作業を行い、終了することだけであると想像してください。その場合、List <T>で利用できる100以上のメソッドは必要なく、IEnumerable <Tで利用できるものだけが必要です>、したがって、以下が適用されるはずです:

public void PerformOperation(IEnumerable<T> myEnumeration) { ... }

そうすることで、あなたと他の開発者は、IEnumerable <T>インターフェイスを実装するクラスのオブジェクトがこのメソッドに与えられることを知っています。リスト、ディクショナリ、または別の開発者が作成したカスタムコレクションクラスの場合があります。

反対に、具体的なList <T>が明示的に必要であると指定した場合(実際にはめったにないことですが、それでも発生する可能性があります)、あなたと他の開発者は、Listまたは継承する別の具体的なクラスでなければならないことを知っていますリストから。


まずは感謝します。さて、懸念事項は、どちらを使用するかをどのように決定するかです。List <T>は両方のインターフェイスを実装しているため、IEnumerableまたはICollectionが必要なすべての場所で常に使用しないでください。常にlistを使用すると、パフォーマンスに影響がありますか?これらの懸念に答えるためにあなたの答えを編集してください
Pankaj Upadhyay

私はあなたのパフォーマンスの質問に答えるように編集
Jalayn

+1ですが、メソッドにリストを渡すことが実際に必要なまれなケースでは、メソッド宣言ではIListなく使用することを追加しますList
コナミマン

@Konamiman- List<>などの特定の機能が必要かどうかによって異なります.AddRange()IList<>それを公開していません。
ボブソン

6

ICollectionおよびIEnumerableの MSDNページをご覧ください

非常に抽象的な言葉で、これは私がこれらのタイプをどのように考えているかです。

IEnumerableは列挙可能なもの、つまり繰り返し処理されるものです。必ずしも「コレクション」を意味するわけではありません。たとえば、IQueryableはIEnumerableを実装し、コレクションではありませんが、オブジェクトを返すためにクエリできるものです。IEnumerableを実装するには、照会時にオブジェクトを返すことができる必要があるのはオブジェクトのみです。私が今日やろうとしているタスクのEnumerableがあると言うかもしれません(私はそれを書き留めておらず、それを定式化していないのでリストではありませんが、私は今やろうとしていることを伝えることができますあなたが「そしてそれから?」と尋ねたら、私はあなたに次のタスクを話すことができるでしょう。

ICollectionはIEnumerableよりも具体的です。主な違いは、コレクションには含まれているアイテムの数がわかっていることです。Enumerableに含まれるアイテムの数を計算するには、効果的にループしてそれらをカウントします。

私:みんな、あなたはそれぞれいくつアイテムを持っていますか?

列挙可能:よくわかりません。さて、ここに一つのアイテムがあります。私は別のものを持っているので、それは2つです。そしてもう1つ、それは3つです...そしてもう1つは... 2382です。

コレクション:2382個のアイテムがあります。私はすでにそれを知っています。

コレクションは、通常、そのすべての要素がどこにあるかをすでに知っているものであり、それらを要求するときに、それらを見つけて生成または生成する必要はありません。それはもっと... Enumerableより具体的です。

私の意見では、EnumerableとCollectionの違いは、CollectionとListの違いよりもはるかに大きいです。実際、コレクションとリストの実際の違いを考えるのに苦労していますが、リストは検索と順序付けのためのより良い方法を提供すると信じています。

他のタイプのコレクションには、QueueおよびStack、およびが含まれDictionaryます。

これらのタイプの名前は非常に便利です。キューとスタックを現実の対応物として考え、リストとの違いを考慮することができます。


「コレクションとリストの実際の違いを考えるのに苦労しています」 ...あなたの答えの後半で、これを自分で答えます。AはListあるICollectionが、ICollection常にではありませんListQueueStackDictionary、...)
スティーブンJeuris

@Stevenそれは非常にとりとめのない答えです。これは重要な違いであることに同意しますが、実際的な違いとは呼びません。ユーザーにとってそれはどういう意味ですか?
カークブロードハースト

それは簡単です!:) when がQueue<int> queue = (Queue<int>)list;スローされます。キューとリストの違いは、この質問の範囲外です。InvalidCastExceptionlistQueue<int>
スティーブンジュリス

IEnumerableの重要な側面は、現在の項目と次の項目を返すことができるということではありません。それを暗示するようなものですが、明示的に言ってはいけません。基本的に、IEnumerableを単独で実装するものは、クエリ時にそのメンバーの任意のアイテムを返すことはできません-現在のアイテムと次のアイテムのみを返します。
コリ

@coriこれは非常に簡潔な方法で、私の答えよりもずっと明確です。
カークブロードハースト

-1

IQueryable:

クエリは、おそらく.ToList()を実行することにより、アイテムを実際に反復するまで実行されません。

IEnumerable:

アイテムの前方専用リスト。アイテム0〜3を渡すことなく「アイテム4」に到達することはできません。読み取り専用リストであるため、追加も削除もできません。それでも遅延実行を使用する場合があります。

IList:

完全にメモリ内の完全なリストへのランダムアクセスは、追加と削除をサポートします

ICollection:

IEnumerableとIListの間です。「最良」とは、要件によって異なります。通常、アイテムのみを表示する場合は、IEnumerableで十分です。少なくとも常に汎用バリアントを使用してください。


この回答は、以前の回答で既に投稿されているものよりも貴重なものを追加するようには見えません
-gnat

それはすべてについての単純な概念です
ジアQammar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.