Сбой в реализации IEnumerable <T>
Я пытаюсь написать собственную (простую) реализацию List. Это то, что я сделал до сих пор:
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()'. 'provaIEnum.Lista.GetEnumerator()' не может реализовать 'System.Collections.IEnumerable.GetEnumerator()', потому что он не имеют соответствующий тип возврата "System.Collections.IEnumerator".
Я не уверен, понимаю ли я, что VS пытается сказать мне, и я понятия не имею, как это исправить.
Спасибо за ваше время
Ответы
Ответ 1
Так как 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];
}
Ответ 2
Прочтите сообщение об ошибке более тщательно; он говорит вам, что именно вы должны делать. Вы не реализовали 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();
}
Ответ 3
Вам также понадобится реализовать не общий метод GetEnumerator:
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
Поскольку интерфейс IEnumerable<T>
расширяет IEnumerable
, вам необходимо реализовать методы, объявленные на обоих.
Ответ 4
Добавьте следующий метод:
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
Ответ 5
Есть две перегрузки GetEnumerator()
, которые вы должны реализовать. Один приходит из IEnumerable<T>
и возвращает IEnumerator<T>
. Другой происходит из IEnumerable и возвращает IEnumerator
. Переопределение должно выглядеть следующим образом:
IEnumerator IEnumerable.GetEnumerator()
Это потому, что IEnumerable<T>
реализует IEnumerable
.
Ответ 6
Так как ваш класс MyList<T>
наследует IEnumerable<out T>
, который, в свою очередь, наследует не-общий IEnumerable
, у вас есть два метода, которые вам нужно реализовать:
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>
и выберите Интерфейс реализации > Интерфейс реализации из контекстного меню.
Ответ 7
У меня возникла аналогичная проблема, хотя я реализовал также IEnumerable и IEnumerable. Я использовал пользовательский тип (класс Person), чем общий тип T.
Для меня причина была в том, что пространство имен не было включено в верхнюю часть файла.
using System.Collections;
После добавления пространства имен это было хорошо для меня.