Использование урожая в С#

У меня есть смутное понимание ключевого слова yield в , но я еще не видел необходимости использовать его в своем коде. Вероятно, это связано с отсутствием понимания этого.

Итак, каковы типичные хорошие обычаи yield?

Ответ 1

yield просто упрощает реализацию перечислителя. Поэтому, если вы хотите написать метод, который возвращает IEnumerable<T>, это избавит вас от необходимости создавать класс перечисления - вы просто yield один результат за раз, а компилятор позаботится о деталях под обложками.

Один удобный случай - написать "бесконечный перечислитель", который вызывающий может вызывать столько раз, сколько нужно. Вот пример, который генерирует бесконечный ряд чисел Фибоначчи: http://chrisfulstow.com/fibonacci-numbers-iterator-with-csharp-yield-statements/ (ну... теоретически бесконечно, но на практике он ограничен размером UInt64).

Ответ 2

Выход реализует шаблон ленивой загрузки. Я предлагаю рассмотреть его полезность с этой точки зрения.

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

Ответ 3

Доходность используется в счетчиках. Компилятор С# автоматически приостанавливает выполнение вашего цикла перечисления и возвращает текущее значение вызывающему.

IEnumerable<int> GetIntegers(int max) {
    for(int i = 1; i <= max) {
         yield return i; // Return current value to the caller
    }
}

- или (более неуклюжий) -

IEnumerable<int> GetIntegers(int max) {
    int count = 0;
    while(true) {
         if(count >= max) yield break; // Terminate enumeration

         count++;
         yield return count; // Return current value to the caller
    }
}

Подробнее о MSDN.

Ответ 4

Также неплохо тестировать и насмехаться, когда вы просто хотите быстро проверить IEnumerable < > , что-то вроде...

yield return somevalue;
yield return someothervalue;
yield return yetanotherone;