tags:

views:

201

answers:

3
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?

+14  A: 

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.

Jon Skeet
A: 

aaaah, sounds good. MoveNext will trigger the Generator (Python) to run. Looks like a lazy called method-body.

thx!

mo
don't reply to stuff in an answer, do it in comments or in your original post, just fyi :)
Allen
A: 

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
jleedev