web-dev-qa-db-ja.com

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

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

_IEnumerable<T>_、_ICollection<T>_、List<T>(Class)の基本的な違いは何ですか?

私は、アプリケーションに問題を感じることなく、それらを使用および交換しているようです。また、これらの3つと交換できる、これらのような類似のジェネリックコレクションは他にありますか?

11
Pankaj Upadhyay

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または継承する別の具体的なクラスである必要があることを知っていますリストから。

19
Jalayn

ICollection および IEnumerable については、MSDNページをご覧ください。

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

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

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

私:皆さん、それぞれにいくつのアイテムを持っていますか?

列挙可能:本当にわかりません。さて、これが1つのアイテムです。私はもう1つ持っているので、2つです。そして、もう1つ、それが3つです...そしてもう1つ...大丈夫、それで2382です。これ以上アイテムがないので、2382を取得しました。もう一度すべて確認する必要があるので、もう一度質問しないでください。

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

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

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

その他の種類のコレクションには、QueueStack、およびDictionaryがあります。

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

6
Kirk Broadhurst