Я понимаю, что это старый вопрос (предварительно Джон Скит?), Но я сам недавно обдумывал этот вопрос. К сожалению, в текущих ответах здесь (на мой взгляд) не упоминается самое очевидное преимущество оператора yield.
Самым большим преимуществом оператора yield является то, что он позволяет перебирать очень большие списки с гораздо более эффективным использованием памяти, чем при использовании, скажем, стандартного списка.
Например, допустим, у вас есть запрос к базе данных, который возвращает 1 миллион строк. Вы можете извлечь все строки, используя DataReader, и сохранить их в List, следовательно, требуя list_size * row_size байтов памяти.
Или вы можете использовать оператор yield для создания итератора и хранить только одну строку в памяти за раз. По сути, это дает вам возможность обеспечить потоковую передачу больших массивов данных.
Более того, в коде, который использует Iterator, вы используете простой цикл foreach и можете решить выйти из цикла по мере необходимости. Если вы делаете перерыв рано, вы не форсируете извлечение всего набора данных, когда вам нужны только первые 5 строк (например).
Относительно:
Ideally some problem that cannot be solved some other way
Оператор yield не дает вам ничего, что вы не могли бы сделать с помощью собственной пользовательской реализации итератора, но избавляет вас от необходимости писать часто сложный необходимый код. Есть очень мало проблем (если таковые имеются), которые не могут быть решены более чем одним способом.
Вот несколько более свежих вопросов и ответов, которые предоставляют более подробную информацию:
Добавлена ли ценность ключевого слова?
Полезен ли урожай за пределами LINQ?