C#, yield return - MoveNext() не меняет значение Current

Рейтинг: 1Ответов: 1Опубликовано: 03.07.2023

Мне не понятно почему в обеих случая выводит в консоль 0, когда в первом случае выполняется MoveNext(), а во втором не выполняется?

using System;
using System.Collections.Generic;

namespace tetst
{
    public class A
    {
        static IEnumerable<int> test()
        {
            yield return 0;
            yield return 5;
            yield return 10;
            yield return 20;
            yield return 50;
        }
        
        static void Main()
        {           
            IEnumerator<int> t = test().GetEnumerator();//первый случай
            t.MoveNext();
            Console.WriteLine(t.Current);//0
            
            IEnumerator<int> x = test().GetEnumerator();//второй случай
            //x.MoveNext();
            Console.WriteLine(x.Current);//0
            
            Console.ReadKey();
        }
    }
}

Ответы

▲ 3Принят

Хороший вопрос. Дело в том, что пока вы не сделали ни единого "шага" - MoveNext(), значение Current будет содержать значение по-умолчанию. А значение по умолчанию для int - это 0. По-этому, может показаться, что MoveNext() ни на что не влияет.

Я немного упростил ваш код и поменял первый yield return так, чтобы он возвращал тройку:

var enumerator1 = Test().GetEnumerator();
enumerator1.MoveNext();
Console.WriteLine("With MoveNext():    " + enumerator1.Current);

var enumerator2 = Test().GetEnumerator();
Console.WriteLine("Without MoveNext(): " + enumerator2.Current);

static IEnumerable<int> Test()
{
    yield return 3;
    yield return 5;
}

Теперь при запуске кода мы увидим следующий вывод:

With MoveNext():    3
Without MoveNext(): 0

Вы можете изучить что генерирует компилятор для этого кода в SharpLab, собственно так я и узнал ответ на ваш вопрос :)