Реализация IEnumerator без использования yield return

Я изучаю концепции итераторов на C # и экспериментирую с кодами, решая простые задачи и пытаясь реализовать по-разному. Я пытаюсь отобразить все термины в списке, для этого пытаюсь разными способами получить результаты. В приведенном ниже коде я использую два класса ListIterator и ImplementList.

В классе ListIterator: я определил HashSet, и он использует IEnumerator для хранения значений. Здесь метод GetEnumerator () возвращает значения в списке. GetEnumerator реализован в классе ImplementList (другой класс). Наконец, список отображается в консоли.

public class ListIterator
{ 
   public void DisplayList()
   {
    HashSet<int> myhashSet = new HashSet<int> { 30, 4, 27, 35, 96, 34};
    IEnumerator<int> IE = myhashSet.GetEnumerator();
    while (IE.MoveNext())
      {
        int x = IE.Current;
        Console.Write("{0} ", x);
      }
      Console.WriteLine();
    Console.ReadKey();
   }
}

В классе ImplementList определена функция GetEnumerator (), которая возвращает список с помощью yield return x.

public class ImplementList : IList<int>
  {
    private List<int> Mylist = new List<int>();
    public ImplementList() { }

    public void Add(int item) 
    { 
        Mylist.Add(item); 
    }

    public IEnumerator<int> GetEnumerator()
    {
      foreach (int x in Mylist)
        yield return x;
    }
  }

Теперь я хочу переписать GetEnumerator () без использования yield return. И он должен вернуть все значения в списке. Можно ли получить все значения в списке без использования yield return в IEnumerator


person Giri    schedule 22.07.2014    source источник


Ответы (2)


Вы можете использовать реализацию Enumerator вашего внутреннего списка MyList:

    public IEnumerator<int> GetEnumerator()
    {
      return MyList.GetEnumerator();
    }

Или вы можете реализовать IEnumerator самостоятельно (из MSDN):

public class People : IEnumerable
{
    private Person[] _people;
    public People(Person[] pArray)
    {
        _people = new Person[pArray.Length];

        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }
    }

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

    public PeopleEnum GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
}

public class PeopleEnum : IEnumerator
{
    public Person[] _people;

    // Enumerators are positioned before the first element 
    // until the first MoveNext() call. 
    int position = -1;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Person Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}
person Liviu Mandras    schedule 22.07.2014
comment
Я реализовал IEnumerator, как использовать его в моем GetEnumerator () - person Giri; 23.07.2014
comment
В моем случае я закодировал список, я не мог проследить, как его использовать в методе GetEnumerator () .. @Liviu M. - person Giri; 23.07.2014
comment
Ты просто return new YourEnumerator(yourInternalList); - person Liviu Mandras; 23.07.2014
comment
Взгляните на мой код Enumerator1 ссылку @Liviu M. - person Giri; 23.07.2014
comment
он показывает некоторую ошибку в Object IEnumerator.Current {....}, поэтому я определил метод Current. тогда это показывает, что ток уже определен. - person Giri; 23.07.2014
comment
Нет необходимости определять новый перечислитель внутри вашего собственного перечислителя. Если вы используете перечислитель внутреннего списка, вы можете просто использовать шаблон из моего первого раздела ответа. Если вы реализуете свой собственный, просто используйте шаблон во втором примере, без наличия нового внутреннего списка целых чисел в перечислителе, потому что вы передаете список извне в перечислитель. - person Liviu Mandras; 23.07.2014

Это вернет результаты в виде массива

return MyList.ToArray();

или если вы хотите вернуть его в виде списка, почему бы просто не

return MyList;
person Jaska    schedule 22.07.2014
comment
он говорит, что не может явно преобразовать список типов в IEnumerator - person Giri; 22.07.2014
comment
Почему вы хотите реализовать список в классе, если он уже реализован самим списком? - person Jaska; 22.07.2014
comment
Я просто экспериментирую с доходностью. Я хочу, чтобы GetEnumerator отображал все значения в списке без использования yield return - person Giri; 22.07.2014
comment
Да, теперь, когда я прочитал ваш вопрос в другой раз, я вижу, вы говорите, что просто экспериментируете :) return MyList.GetEnumerator (); - person Jaska; 22.07.2014
comment
могу ли я использовать цикл for для получения всех значений ?? Я пытался писать с помощью цикла for, но он возвращает только одно значение. @Jaska - person Giri; 22.07.2014
comment
var a = новый MyList (). GetEnumerator (); while (a.MoveNext ()) {Console.WriteLine (a.Current); } - person Jaska; 22.07.2014
comment
так что эта часть должна быть написана в общедоступном IEnumerator ‹int› GetEnumerator () {....} Я прав ?? - person Giri; 22.07.2014
comment
На самом деле, если вы хотите пройти через этот список (который сам по себе является IEnumerable), вы можете изменить метод GetEnumerator () на следующий: public IEnumerable ‹int› GetAsEnum () {вернуть MyList как IEnumerable ‹int›; } - person Jaska; 22.07.2014
comment
эй, я поместил код (var a = new MyList () ......) в GetEnumerator (), он показывает некоторую ошибку MyList - это поле, но используется как тип. - person Giri; 22.07.2014
comment
Я получил ошибку. ImplementList.MyList - это «поле», но используется как «тип» .. @Jaska - person Giri; 23.07.2014