Весь смысл итераторов - именно то, что вы видите.Предполагается, что итератор откладывает выполнение до фактического использования результатов.В вашем коде метод I
не является итератором, поэтому его тело выполняется до конца при вызове.Метод Cross
является итератором, поэтому его тело не будет выполнено, пока вы не используете результат.
Например, если бы вы использовали цикл foreach
для перечисления _cross
, вы бы увидели, чтокаждая итерация цикла приведет к попаданию ключевого слова yield
в методе Cross
.После нажатия yield break
метод завершится, и ваш цикл завершится.
В качестве примера того, почему это хорошо, давайте сравним метод File.ReadAllLines
и метод File.ReadLines
.Первый появился с .NET 1.0, а второй - гораздо позднее.Метод ReadAllLines
читает весь файл и разбивает его на строки, а затем возвращает массив, содержащий эти строки.Это означает, что вы не можете начать обработку файла, пока все его содержимое не будет прочитано.Это также означает, что вы должны прочитать все содержимое, даже если оно вам не нужно.Например, если миллион строк и вы хотите, чтобы первая содержала определенное слово, вам пришлось бы читать каждую строку, даже если вы нашли слово в десятой строке.
Для сравнения, ReadLines
метод итератор.Он не начинает чтение файла до тех пор, пока вам действительно не нужны данные, и он считывает данные только по мере необходимости.Это означает, что вы можете обрабатывать данные по мере их чтения, а не ждать, пока они все будут прочитаны, чтобы начать обработку.Это также означает, что вам не нужно читать больше данных, чем требуется, например, если вы начнете искать слово и найдете его в десятой строке, оставшиеся 999 990 строк не будут прочитаны.