Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot print to console using yield return

In the tests below, I cannot get Console.WriteLine to really print when using yield return. I'm experimenting with yield return and I understand I have something missing in my understanding of it, but cannot find out what it is. Why aren't the strings printed inside PrintAllYield?

Code:

class Misc1 {
    public IEnumerable<string> PrintAllYield(IEnumerable<string> list) {
        foreach(string s in list) {
            Console.WriteLine(s); // doesn't print 
            yield return s;
        }
    }
    public void PrintAll(IEnumerable<string> list) {
        foreach(string s in list) {
            Console.WriteLine(s); // surely prints OK
        }
    }
}

Test:

[TestFixture]
class MiscTests {
    [Test]
    public void YieldTest() {
        string[] list = new[] { "foo", "bar" };
        Misc1 test = new Misc1();

        Console.WriteLine("Start PrintAllYield");
        test.PrintAllYield(list);
        Console.WriteLine("End PrintAllYield");

        Console.WriteLine();

        Console.WriteLine("Start PrintAll");
        test.PrintAll(list);
        Console.WriteLine("End PrintAll");
    }
}

Output:

Start PrintAllYield
End PrintAllYield

Start PrintAll
foo
bar
End PrintAll

1 passed, 0 failed, 0 skipped, took 0,39 seconds (NUnit 2.5.5).
like image 232
henginy Avatar asked Dec 22 '22 07:12

henginy


1 Answers

You have to actually enumerate the returned IEnumerable to see the output:

    Console.WriteLine("Start PrintAllYield");
    foreach (var blah in test.PrintAllYield(list))
        ; // Do nothing
    Console.WriteLine("End PrintAllYield");

When you use the yield return keyword, the compiler will construct a state machine for you. Its code will only be run when you actually use it to iterate the returned enumerable.

Is there a particular reason you're trying to use yield return to print out a sequence of strings? That's not really the purpose of the feature, which is to simplify the creation of sequence generators, rather than the enumeration of an already generated sequence. foreach is the preferred method for the latter.

like image 115
dlev Avatar answered Jan 10 '23 21:01

dlev