Подтвердить что ты не робот

Сбой в реализации 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 пытается сказать мне, и я понятия не имею, как это исправить.

Спасибо за ваше время

4b9b3361

Ответ 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; 

После добавления пространства имен это было хорошо для меня.