Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

yield break; - crazy behaviour

Tags:

yield

c#

.net

break

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace ConsoleApplication4
{
    class Program
    {
        static void Main (string[] args)
        {
            var test1 = Test1(1, 2);
            var test2 = Test2(3, 4);
        }

        static IEnumerable Test1(int v1, int v2)
        {
            yield break;
        }

        static IEnumerable Test2 (int v1, int v2)
        {
            return new String[] { };
        }
    }
}

"test1" seems to be an IEnumerable with v1 and v2 (params) as fields and "Test1" is NOT called.

"Test2" works a "designed" :)

whats going on?

like image 988
mo. Avatar asked Sep 24 '09 13:09

mo.


2 Answers

Test1 is called, but unless you iterate through the result, you won't hit a breakpoint on yield break.

Basically Test1 is transformed into a state machine which implements IEnumerable for you... but all of the body of your method is inside that state machine, and unless you use the state machine by calling GetEnumerator() and then MoveNext() (or using a foreach loop) you won't see your body execute.

See my general iterator article and my iterator implementation article for more information, and also two of Eric Lippert's blog posts: Psychic Debugging part one and Psychic Debugging part two.

like image 132
2 revs Avatar answered Oct 13 '22 11:10

2 revs


Since you mentioned Python, I'm going to point out that generators in Python work quite similarly to generators in C#. There's just the small difference that yield break alone can transform a C# method into a generator, while the Python equivalent of raise StopIteration won't.

>>> def f():
...     print "Beginning of generator"
...     if False: yield
...     print "End of generator"
... 
>>> it = f()
>>> it
<generator object at 0x94fae2c>
>>> it.next()
Beginning of generator
End of generator
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
like image 28
Josh Lee Avatar answered Oct 13 '22 11:10

Josh Lee