2009-04-19 84 views

答えて

80

IEnumerableは、最小限の "反復可能"機能しか提供しません。シーケンスをトラバースすることはできますが、それはそれです。これには欠点があります。たとえば、IEnumerableを使用して要素を数えたり、n番目の要素を取得することは非常に非効率的ですが、利点もあります。たとえば、IEnumerableは素数のシーケンスのような無限のシーケンスです。

アレイはランダムアクセスの固定サイズのコレクションです(インデックスに登録できます)。

リストは、ランダムアクセスで可変サイズのコレクションです(要素の追加や削除が可能です)。

のIList等リストの機能を抽象化インターフェース(、削除、追加、インデクサアクセスカウント)離れるよう一覧するBindingList、のObservableCollectionなどの種々の具体的なクラスから、

+2

ここに受け入れられた答えによるとhttp://stackoverflow.com/questions/1826658/what-is-faster-or-preferred-ienumerable-toarray-or-tolist。 IEnumerableのカウントはICollectionのCountとほぼ同じです。 – Karsten

+12

はい、いいえ。 Count()拡張メソッドは、IEnumerableもICollectionであるかどうかをチェックし、IEnumerableがICollectionである場合はCountプロパティを呼び出します。 IEnumerable *がICollectionでない場合、Count()はシーケンスの反復処理に戻ります。おそらく、IEnumerableの存在が、オブジェクトに1つしかない場合はより効率的なメソッドを使用し、LINQ to Objects拡張メソッドを使用することを止めるわけではないので、「* only * IEnumerableを使用して要素を数えるのは非常に効率が悪い」と言わなければなりません正確にそれをしてください。 – itowlson

9

IEnumerableおよびIListはinterfacesです。配列とリストはクラスです。配列はIEnumerableを実装します。 Listは、IEnumerableを拡張するIListを実装します。

編集:コメントにitowlsonと記されているように、ArrayはIListも実装しています。

+4

配列もIListを実装しています。 – itowlson

+0

私もやらなかった!配列上でIList.RemoveAtを呼び出すとどうなりますか? –

+0

NotSupportedExceptionをスローします。 (注意IList.RemoveAtと同様のIListメソッドはArray上に明示的に実装されているため、通常のArray参照には表示されません) – itowlson

13

IEnumerableは、アイテムのコレクションを通じて(たとえばforeachキーワードを使用して)反復を可能にするインターフェイスです。

配列は.NET組み込み関数です。同じ種類の項目を保持しますが、固定サイズです。 x要素で配列を作成すると、配列は拡大または縮小できません。

IListはリストのインターフェイスを定義し、IEnumerableも実装しています。

リストはIListインターフェイスを実装しています。それはリストの具体的なタイプです。

.NETリストと配列の違いは、リストに要素を追加できることです。必要な項目をすべて保持できるほど大きくなっています。このリストはこれを内部的に配列に格納し、配列の要素がすべて保持できるほど大きくなければ、新しい配列が作成され、項目がコピーされます。

IList &配列は両方ともIEnumerableを実装します。それがインターフェイスの仕組みです - クラスは契約を実装し、同様の方法で動作し、結果として同様に扱うことができます(クラスがIEnumerableを実装していることを知っていれば、howsまたはwhysを知る必要はありません)。私はあなたがインターフェイスなどを読むことをお勧めします。

+1

すべての答えを読んでいない読者にこのコメントを追加する:配列とList <>はどちらもIList <>を実装するおそらく多くのメンバーがNotSupportedExceptionをスローしているためです)。 IListはIEnumerableを継承していると言うよりも、IEnumerableを継承しています。 – phoog

2

IEnumerable、その汎用インターフェースであります誰かがコレクションを繰り返し処理できるように、Array,ListStringなど多くのクラスで使用されています。基本的には、それはforeachステートメントを駆動するものです。

IListは、一般に、タイプListの変数をエンドユーザーに公開する方法です。このインタフェースは、基になるコレクションへのランダムアクセスを許可します。

6

IEnumerableコレクションの生成は遅延です。 例:メソッドで

public IEnumerable<int> GetTwoInts() 
{ 
    yield return 1; 
    yield return 2; 
} 
public void Something() 
{ 
    var twoInts = GetTwoInts(); 
} 

GetTwoInts()の呼び出しが実際に列挙が繰り返し処理されることはありませんので、実行されている方法のGetTwoIntsにはなりません何か。

+0

少し詳しく教えていただけますか?私はそれを正しく理解するかどうかはわかりません。実際にそのメソッドが実行される結果となるコード行を後で表示できますか? ありがとう! – paaone

+0

@paaone 'twoInts'を' foreach'に入れたり、 'twoInts.ToList()'を呼び出します。 – row1

0

これは古い投稿ですが、依然として返信が考えられます。 IEnumerableは、配列がデータ構造(固定サイズの要素の連続したコレクションで、インデックスで要素にアクセスするのを容易にする)である間の動作です。 配列がIEnumerableを実装するとき、IEnumerableの固有のプロパティを表現することも想定されています(コレクションの反復を容易にする)。

0

foreachステートメントを実行すると、のパフォーマンス差IList<T>List<T>の間にあることに注意してください。 IList<T>.GetEnumeratorによって返されるいずれかの基準型であり、したがって、メモリの割り当てを要求に対しList<T>.GetEnumeratorによって返されるイテレータオブジェクトは(Enumerator of value type of list in c#を参照)の値型であるためだ

私の意見では、IList<T>はとにかくとても良いインターフェースではありません。たとえば、Addを呼び出すと投げることができます(Why array implements IList?参照)。カプセル化が必要な場合は、IEnumerable<T>またはIReadOnlyList<T>を使用する方がよいでしょう。

関連する問題