2011-02-11 25 views
37

IEnumerableIEnumerable<T>の違いは何ですか?IEnumerableとIEnumerableの違い<T>?

私はこれらの両方のインターフェイスを実装するフレームワーククラスを多数見てきました。したがって、両方を実装することで得られる利点を知りたいのですが?

、彼らが定義されてきたかを見てください:

public interface IEnumerable 
{ 
    [DispId(-4)] 
    IEnumerator GetEnumerator(); 
} 
public interface IEnumerable<T> : IEnumerable 
{ 
    IEnumerator<T> GetEnumerator(); 
} 

我々は見ての通り、IEnumerable<T>IEnumerable<T>継承、IEnumerableが持っているものは何でも意味し、IEnumerableから派生し、その後、なぜ我々は両方の代わりに、ちょうどIEnumerable<T>を実装してください? IEnumerable<T>を実装するだけでは十分ではありませんか?

は同様に、他の同様のペアがあります

  • IListIList<T>
  • ICollectionICollection<T>

私もこれらについて知りたいです。

答えて

48

基本的に非活性インターフェイスが.NET 1.0および1.1で最初に登場しました。その後、.NET 2.0が出てきたとき、それに相当するものが出てきました。あなたは基本的にの両方を実装するを持っている、と明示的なインターフェイスを使用する必要があります - 人生はジェネリックが実装面では、.NET 1.0 :)

に代わり、両方の「のみ」IEnumerable<T>それを作った場合にはずっと簡単だっただろう両方ともパラメータなしのGetEnumeratorメソッドを定義すると、実装も同じです。一方

public IEnumerator<T> GetEnumerator() 
{ 
    // Return real iterator 
} 

// Explicit implementation of nongeneric interface 
IEnumerator IEnumerable.GetEnumerator() 
{ 
    // Delegate to the generic implementation 
    return GetEnumerator(); 
} 

、あなたはめったに幸い、手によって完全にこれらのものを実装する必要がありません(yield returnなどで)C#2で導入されたイテレータブロックと:IEnumerator<T>はあまりにもIEnumeratorを拡張するとして、それは通常、このようなものです。上記のような記述が必要な場合は、GetEnumeratorメソッドでyield returnを使用する必要があります。 IList<T>ないIListを拡張しない、とICollection<T>ICollectionを延長しないことを

は注意してください。これは型の安全性が劣るからです...一般的なイテレータは、任意の値のobject,IListおよびICollectionへの変換(潜在的にボクシング)のために、非永続的なイテレータとして見なすことができますが、にコレクション; IList<int>に文字列を追加することは意味がありません。

編集:私たちがIEnumerable<T>を必要とする理由は、タイプセーフな方法で反復し、その情報を伝播できるようにするためです。 IEnumerable<string>を返すと、返されたすべての文字列が文字列リファレンスまたはnullであると見なすことができます。 IEnumerableの場合、CurrentプロパティがIEnumeratorの場合はobjectなので、シーケンスから返された各要素を効果的にキャストする必要があります(foreachステートメントに暗黙的に記述する必要があります)。なぜ我々はまだIEnumerableを必要とする - 古いインターフェイスは決して遠く離れて行くことがないため。それを使用している既存のコードが多すぎます。

それはIEnumerableを拡張しないIEnumerable<T>可能だっただろうが、その後IEnumerable<T>を利用することを希望する任意のコードがIEnumerableを受け入れるメソッドを呼び出すことができませんでした - と.NET 1.1からそのようなメソッドの多くがありました1.0。

+12

ジェネリックスが.NET 1.0にそれを作ったなら、人生はもっと簡単になったはずです... – Oded

+0

@Jon:質問は:なぜIEnumerable 'を既に実装している場合でも' IEnumerable'を実装する必要がありますか? 、またはその逆? – Nawaz

+0

@Nawaz:答えを編集しました。なぜジェネリック医薬品が良いのかという考えをあなたはどれくらい快適に感じていますか? –

5

一つのIEnumerable < T>は、IEnumerableをを実装し、その必要はないが、ある十分なのに、あなたは両方を定義するクラスを参照してください理由としてObject型のオブジェクト、他の戻り型T

2

のオブジェクトを返すがいいですサブインターフェースを時折リストするために自己文書化する。検討してください。

interface IA { } 
interface IB : IA { } 

class A : IB {} // legal, IB implements IA 

class B : IA, IB {} // also legal, possible more clear on intent 
1

ループIEnumeratorを反復処理すると、状態が維持されます。 カーソル位置を覚えています。IEnumerableはカーソル位置を記憶していません。

関連する問題