Edward83
Edward83

Reputation: 6686

yield in C# by infinite loop example

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?

Upvotes: 2

Views: 2424

Answers (3)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

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
}

Upvotes: 12

wiero
wiero

Reputation: 2246

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.

Upvotes: 1

Eren Ers&#246;nmez
Eren Ers&#246;nmez

Reputation: 39085

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)
}

Upvotes: 1

Related Questions