2012-01-06 19 views
26

私は自分の(単純な)リストの実装を書こうとしています。これは私がこれまでにやったことです:IEnumerableを実装する際のトラブル<T>

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace provaIEnum 
{ 
    class MyList<T> : IEnumerable<T> 
    { 
     private T[] _array; 
     public int Count { get; private set; } 

     public MyList() { /* ... */ } 
     public void Add(T element) { /* ... */ } 

     // ... 

     public IEnumerator<T> GetEnumerator() 
     { 
      for (int i = 0; i < Count; i++) 
       yield return _array[i]; 
     } 
    } 

私もGetEnumeratorのトピックに関するエラーを取得しています:

「provaIEnum.Listaは、」インターフェイスメンバ 「System.Collections.IEnumerable.GetEnumeratorを実装していません。 () '。 'System.Collections.IEnumerator'の一致する戻り値の型が ではないため、 'provaIEnum.Lista.GetEnumerator()'には 'System.Collections.IEnumerable.GetEnumerator()'が実装できません。

VSが私に教えようとしていることを理解していて、それを修正する方法がわかりません。お時間を

おかげで

+0

現在、内部配列を 'foreach'で変更することができるので、列挙子を書くべきではないことに注意してください(foreachでは例外を発生させないで' Add'を呼び出してください)。 [参照](参照:http://stackoverflow.com/questions/24142614/when-should-i-separately-implement-ienumeratort) – nawfal

+0

@nawfal良い点、バグは常に私たちを見ている;) – BlackBear

答えて

41

IEnumerable<T>ので、実装はIEnumerableあなたはGetEnumerator方法の非ジェネリックバージョンを持っているあなたのクラスでもこのインタフェースを実装する必要があります。競合を避けるためには、明示的にそれを実現することができます。

IEnumerator IEnumerable.GetEnumerator() 
{ 
    // call the generic version of the method 
    return this.GetEnumerator(); 
} 

public IEnumerator<T> GetEnumerator() 
{ 
    for (int i = 0; i < Count; i++) 
     yield return _array[i]; 
} 
+1

ありがとう、私は知らなかったIEnumerable はIEnumerableを実装しています(それは明らかです:P) – BlackBear

+5

'System.Collections.'を使用して' IEnumerator'と 'IEnumerable.GetEnumerator'を明示的に修飾していないので、これは失敗します。 IEnumeratorにジェネリック引数が必要だと言っています。 – PJTraill

10

あなたにも非ジェネリックGetEnumeratorメソッドを実装する必要があります、あなたが実装する必要が

IEnumerator IEnumerable.GetEnumerator() 
{ 
    return GetEnumerator(); 
} 

IEnumerable<T>インタフェースはIEnumerableを拡張するので、両方で宣言されたメソッド。

+0

明示的なインターフェイスの実装には、「標準的な方法」のためのアクセス修飾子 – Nuffin

36

エラーメッセージをより注意深く読んでください。あなたがしなければならないことを正確に伝えています。 System.Collections.IEnumerable.GetEnumeratorを実装していません。

一般名IEnumerable<T>を実装する場合は、System.Collections.IEnumerableのGetEnumeratorも実装する必要があります。

そうする標準的な方法は次のとおりです。

public IEnumerator<T> GetEnumerator() { whatever } 
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
{ 
    return this.GetEnumerator(); 
} 
+0

+1が必要ではありません。 – BlackBear

4

は、次のメソッドを追加:

IEnumerator IEnumerable.GetEnumerator() 
{ 
    return this.GetEnumerator(); 
} 
2

をあなたが実装する必要がありGetEnumerator()の2つのオーバーロードがあります。 1つはIEnumerable<T>から来て、IEnumerator<T>を返します。もう1つはIEnumerableから来て、IEnumeratorを返します。オーバーライドは次のようになります。

IEnumerator IEnumerable.GetEnumerator()

IEnumerable<T>IEnumerableを実装しているためです。あなたのクラス以来

1

、今度は非ジェネリックIEnumerableを継承MyList<T>継承IEnumerable<out T>、あなたが実装する必要がある2つの方法があります:あなたは、あなたのクラスを宣言するときに

IEnumerator<T> IEnumerable<T>.GetEnumerator() 
     { 
      throw new NotImplementedException(); 
     } 

     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     { 
      throw new NotImplementedException(); 
     } 

これを行う簡単な方法は次のとおりです。

class MyList<T> : IEnumerable<T> 

IEnumerable<T>テキストをクリックして、インターフェイス>は明示的コンテキストメニューからインタフェースを実装する実装を選択します。

0

IEnumerableとIEnumerableも実装しましたが、同様の問題が発生しました。ジェネリック型Tよりもカスタム型(Personクラス)を使用していました。私にとっては、名前空間がファイルの先頭に含まれていなかったからです。

using System.Collections; 

名前空間を追加した後、それは私にとっては良かったです。

関連する問題