С#: Пользовательский IEnumerator?

Это сообщение относится к C# в Unity, но я предполагаю, что общие знания C# будут применимы.

Возьмите следующий код:

class myClass
{
    IEnumerator myEnumerator;
    public IEnumerator theEnumerator()
    {
        int i = 0;
        while (true)
        {
            Debug.Log(i++);
            yield return null;
        }
    }

    public void Update()
    {
        if (myEnumerator == null) { myEnumerator = theEnumerator(); }
        myEnumerator.MoveNext();
    }
}

Если я создаю экземпляр этого класса, а затем вызываю «Обновить» один раз за кадр, я получаю в журнале следующий вывод:

0
1
2
3
4...

Это отлично работает, однако я хочу реализовать некоторые пользовательские функции в самом IEnumerator. Но если я создам следующее:

public class myIEnumerator : IEnumerator
{
    public int myCustValue;
    public void myCustFunction(){}
}

а затем обновите класс oringal, заменив "IEnumerator" на "myIEnumerator", я получаю следующую ошибку:

The body of `myClass.theEnumerator()' cannot be an iterator block because `myIEnumerator ' is not an iterator interface type

Что я здесь делаю неправильно и как мне создать свой собственный IEnumerator?


person Tyson    schedule 02.12.2015    source источник
comment
Я думаю, что это проблема компилятора, а компилятор поддерживает только IEnumerable, IEnumerable<T>, IEnumerator и IEnumerator<T>. Наследование не работает для блоков итераторов.   -  person Enigmativity    schedule 03.12.2015
comment
Он находится в документах, методах итераторов и средствах доступа get. итератор должен соответствовать следующим требованиям: Тип возвращаемого значения должен быть IEnumerable, IEnumerable‹T›, IEnumerator или IEnumerator‹T›. Объявление не может иметь никаких параметров ref или out.   -  person Patrick    schedule 03.12.2015


Ответы (2)


Вы можете использовать yield только в методе, возвращаемый тип которого IEnumerator, IEnumerable, IEnumerator<T> или IEnumerable<T>. Вы не можете изменить возвращаемый тип метода на тип, который реализует один из этих интерфейсов, это не имеет смысла.

Причина этого в том, что компилятор C# генерирует специальный класс, который реализует один из этих 4 интерфейсов (на самом деле он реализует как IEnumerator, так и IEnumerable или их общие версии), и экземпляр этого сгенерированного компилятором класса — это то, что на самом деле возвращается из метода. . Изменяя возвращаемый тип, вы пытаетесь сказать, что компилятор создаст экземпляр вашего класса, который будет выполнять перечисление. Но он не может этого сделать, потому что на самом деле ничего не знает о вашем классе (и на самом деле ваш класс может даже неправильно перечислять).

person Kyle    schedule 02.12.2015
comment
А, это имеет смысл. Спасибо за объяснение! - person Tyson; 03.12.2015

Я не знаком с Unity, но думаю, вам нужно реализовать интерфейс IEnumerator. Методы MoveNext()и Reset()отсутствуют.

Взгляните на интерфейс IEnumerator< /а>

person frank    schedule 02.12.2015