доходность возврат использования

Подход 1:

class myClass
{
   List<SomeType> _list;

   IENumerator<SomeType> GetEnumerator()
   {
      foreach(SomeType t in _list)
        yield return t;
   }
}

myClass m = new myClass();
List<SomeType> list;
...
foreach(SomeType t in m)
  list.Add(t);

Подход 2:

class myClass
{
    public List<SomeType> _list {get; private set;}
}

myClass m = new myClass();
...
List<SomeType> list = m.list;

Какой подход лучше? Если во-вторых, не могли бы вы показать мне, как реально использовать возврат доходности?


person Ivan Prodanov    schedule 22.11.2012    source источник
comment
Что ж, если вам нужен перечислитель, используйте первый, если вам нужен список, используйте второй. Это разные вещи. stackoverflow.com/questions/17125 /   -  person looper    schedule 22.11.2012
comment
А List<T> уже есть GetEnumerator реализация ???   -  person Jodrell    schedule 22.11.2012
comment
Что вы на самом деле спрашиваете, когда я могу использовать yield return?   -  person Jodrell    schedule 22.11.2012


Ответы (3)


Класс со свойством-коллекцией обычно лучше всего делать в виде списка, чтобы его можно было повторять несколько раз и изменять. Это невозможно для счетчика, который представляет собой просто последовательность. Типичные случаи использования счетчиков:

  • фильтрация данных на лету (например, Enumerable.Where)
  • reading individual items sequentially from a file that contains multiple records, without loading them all at once
    • or network socket
    • или сервер базы данных
  • предоставление оболочки только для пересылки и только для чтения над последовательностью данных
  • и т.д
person Marc Gravell    schedule 22.11.2012

Ни один.

Если вам нужен перечислитель и у вас уже есть базовый тип IEnumerable (List реализует IList, который расширяет IEnumerable), просто верните его следующим образом:

public IEnumerator<SomeType> GetEnumerator ()
{
    return _list.GetEnumerator();
}

В противном случае, если вам действительно нужен список, то есть произвольный доступ с использованием индексов, тогда верните IList; и если вы действительно хотите вернуть его внутренний тип реализации, то есть List, вы можете просто сделать его доступным свойством. Однако обратите внимание, что частный сеттер не предотвращает изменение списка (добавление или удаление элементов и т. Д.). Если вы этого хотите, верните вместо этого список только для чтения:

public IList<SomeType> List
{
    get { return _list.AsReadOnly(); }
}

Что касается доходности

не могли бы вы показать мне реальное доказательство использования доходности?

yield return полезно, когда у вас действительно есть генератор, когда вам действительно нужно сгенерировать следующий элемент. Простым примером может служить генератор случайных чисел, который предоставляет вам другое случайное число, если вы продолжаете его спрашивать. Этому не обязательно есть конец, но вы можете не знать количество чисел до начала.

Другое распространенное использование - это все, что извлекает данные из какого-либо внешнего источника. Например, список элементов из веб-сервиса. Прежде чем вы не знаете, сколько элементов есть, и вы не обязательно знаете, сколько элементов вы на самом деле хотите (поскольку вы, возможно, захотите отобразить его на бесконечном дисплее, показывая по одному). В этом случае вы могли бы сделать это так:

IEnumerable<Item> GetItems()
{
    while (Service.HasMorePages())
    {
        foreach (Item item in Service.GetNextPage())
        {
            yield return item;
        }
    }
    yield break;
}

GetNextPage всегда будет возвращать список из N элементов за раз, и вы получите следующий, когда захотите больше элементов, чем вы уже получили.

person poke    schedule 22.11.2012

Возможности безграничны,

public IEnumerator<int> FibonnaciSeries()
{
    int a = 1;
    int b = 1;

    yield return 1;
    yield return 1;

    while (true)
    {
        var c = a + b;
        a = b;
        b = c;
        yield return c;
    }
}

Есть ли один тривиальный пример, который приходит на ум, является ли серия Фибонначи реальным миром?


Это не самая эффективная из возможных реализаций.

person Jodrell    schedule 22.11.2012
comment
вы будете удивлены, насколько часто это не встречается в повседневном программировании в реальном мире; p - person Marc Gravell; 22.11.2012
comment
@MarcGravell Должен признаться, я не жаждал его добавления в фреймворк. - person Jodrell; 22.11.2012
comment
@Jodrell Если вы добавите Фибоначчи, вам придется добавить и множество других распространенных алгоритмов; и тогда у вас возникнет проблема бесконечного обсуждения того, что добавить, а что не добавить. Кроме того, как вы сами сказали, это не самая эффективная из возможных реализаций, и для большинства алгоритмов «эффективность» полностью зависит от ваших потребностей, поэтому в любом случае будет сложно добавить «идеальное» решение. При этом вы знаете, что числа Фибоначчи имеют закрытую форму? - person poke; 22.11.2012
comment
Реализация с индексатором, поддерживающим BigInteger, представляет собой гораздо более интересную проблему, но еще менее повседневную и определенно выходит за рамки вопроса. - person Jodrell; 22.11.2012
comment
@poke, боюсь, мой сарказм плохо отражался в моем предыдущем комментарии. На самом деле я использовал серию Фибонначи только для ответа на вопрос о SO. - person Jodrell; 22.11.2012
comment
@Jodrell Да ладно, я скучал по сарказму, да. Но в этом есть смысл… ^^ - person poke; 22.11.2012