2

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?

3 Answers 3

12

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 } 
Sign up to request clarification or add additional context in comments.

6 Comments

did you try to compile it yourself.it doesn't compile with foreach.because it doesn't return an IEnumerable and doesn't implement it. it will compile with while, and still it is INFINITE. because WHILE LOOP NEVER STOP
@Selman22 Updated my answer. btw What's wrong with INFINITE loop? If that is the intension what's wrong?
@SriramSakthivel did you read the question ? This code only tries to run once Begin function and call infinite times function Play. If that was the intent I'm pretty sure question would be different!
@Selman22 I've read the question. You should read the question carefully. OP states his code is trying to call Begin once and Play infinitely which doesn't work and solved now. Get it? If not look at MainLoop method everything will become clear
it's not my fault.What I understand from that words,OP has an infinite loop and he asks for why? if he want to make an infinite loop and he can't get it then he should say why can't I get an infinite loop? or this code should do this BUT IT DOESN'T. get it ?
|
1

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

3 Comments

+1 Haters gonna hate, nevermind. Good answer.. Me too got downvote as well :(
THIS IS STILL AN INFINITE LOOP. and that code doesn't compile with foreach.before writing an answer you should try to compile it yourself
@Edward83 because it is WRONG
1

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.

3 Comments

it wasnt't me who downvoted other reposnses, despite the fact i don't recommend foreach ( and yes i know it is an example ) ( i'm writing this as third response )
in my example not IEnumerable returns but IEnumerator. But thank you for answer.
oops sorry, this must be because of my linq addiction, i see ienumerable everywhere ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.