Вопрос

Помимо (IEnumerable возвращает GetEnumerator (), для " foreach " IEnumerble необходим))

почти два следующих подхода позволяют нам перебирать коллекцию. Что такое

преимущество одного над другим? (Я не спрашиваю разницу между IEnumerable и IEnumerator).

static void Main()
{
    IEnumerator<int> em = MyEnumerator<int>(new int[] { 1, 2, 3, 4 });
    IEnumerator<int> e = Collection<int>
                        (new int[] { 1, 2, 3, 4 }).GetEnumerator();

    while (em.MoveNext())
    {
        Console.WriteLine(em.Current);
    }

    while (e.MoveNext())
    {
        Console.WriteLine(e.Current);
    }
    Console.ReadKey(true);
}

подход 1

 public static IEnumerator<T> MyEnumerator<T>(T[] vals )

 {
     T[] some = vals;

     foreach (var v in some)
     {
       yield return v;
     }
}

подход 2

public static IEnumerable<T> Collection<T>(T[] vals)
     {
         T[] some = vals;

         foreach (var v in some)
         {
             yield return v;
         }
     }
Это было полезно?

Решение

Основное отличие состоит в том, что большинство API поддерживают импульс IEnumerable<T>, но не IEnumerator<T>.

Вы также должны помнить, чтобы вызывать Reset () при его использовании, в то время как синтаксис более очевиден в GetEnumerator (просто позвоните RandomEnumerable еще раз). Также см. Комментарий Эрика Липпера о том, что перезагрузка - плохая идея; если Reset не реализован в вашем RangeEnumerable или содержит ошибки, он становится одноразовым перечислителем (во многих случаях довольно бесполезным).

Другое отличие может заключаться в том, что у вас может быть Reset(), который может быть перечислен из нескольких потоков одновременно, но <=> хранить одну позицию в перечисленных данных (представьте себе <=> или <=>).

Таким образом, вывод заключается в том, что <=> более универсален, но в любом случае, если у вас есть функция, возвращающая <=>, генерирующую <=> вокруг нее, это просто.

class EnumeratorWrapper<T> : IEnumerable<T>
{
    Func<IEnumerator<T>> m_generator;
    public EnumeratorWrapper(Func<IEnumerator<T>> generator)
    {
        m_generator = generator;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return m_generator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return m_generator();
    }
}

Просто для согласованности API использование <=> кажется лучшим решением для меня.

Но проблема с <=> в <=> делает его в любом случае непригодным решением, поэтому <=> - это путь.

Другие советы

Поправьте меня, если я ошибаюсь, но единственная разница - это разница между IEnumerable и IEnumerator, и, поскольку вы специально сказали, что не спрашиваете разницу, оба хороши ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top