Question

I am trying to understand how yield works in C#. For testing I made some example code:

using System;
using System.Text;

namespace ConsoleApplication1
{
    class GameFrame
    {
    };

    class GameState
    {
        public static GameFrame Begin()
        {
            Console.WriteLine("GameState.Begin");

            return new GameFrame();
        }

        public static GameFrame Play()
        {
            Console.WriteLine("GameState.Play");

            return new GameFrame();
        }

        public static System.Collections.Generic.IEnumerator<GameFrame> MainLoop()
        {
            yield return Begin();

            while (true)
            {
                yield return Play();
            }
        }
    };


    class Program
    {
        static void Main()
        {
            while (GameState.MainLoop() != null)
            {
            }
        }
    }
}

This code only tries to run once Begin function and call infinite times function Play. Please tell me why I never see my messages in console?

Was it helpful?

Solution

You need to enumerate the collection, You just check whether the result is null or not, that will not start the enumeration.

foreach (var frame in GameState.MainLoop())
{
    //Do whatever with frame
}

To make it work with `foreach you can make the MainLoop method return IEnumerable<GameFrame> instead of IEnumerator<GameFrame> Or just use

var enumerator = GameState.MainLoop();
while (enumerator.MoveNext())
{
     //Do whatever with enumerator.Current
}

OTHER TIPS

That's because you get back an IEnumerable<GameFrame>, but never actually iterate through it.

Try this instead:

var frames = GameState.MainLoop();
foreach(var frame in frames)
{
    // use the frame
    // e.g. frame.Show(); (note: in your example code, 
    // GameFrame doesn't have any members)
}

GameState.MainLoop() returns IEnumerable which represents infinite collection from which you can take items. When you're using yield, elements are evaluated only when they are needed so you will see some output only if you "touch" and item

 GameState.MainLoop().Take(5).ToList();

I don't recommend using foreach with infinite loops.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top