2009-09-24 7 views
6
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" parece ser un IEnumerable con v1 y v2 (params) como campos y "Test1" NO se llama.ruptura de rendimiento; - comportamiento loco

"Test2" funciona un "diseñado" :)

que hay de nuevo?

Respuesta

15

Test1 es llamado, pero a menos que iterar a través del resultado, no se alcanzó un punto de interrupción en yield break.

Básicamente Test1 se transforma en una máquina de estados que implementa IEnumerable para usted ... pero todo el cuerpo de su método es dentro de esa máquina de estados, ya menos que utiliza la máquina de estado llamando GetEnumerator() y luego MoveNext() (o usando un bucle foreach) no verá que su cuerpo se ejecute.

Véase mi artículo y mi general iterator articleiterator implementation para más información, y también dos de las entradas del blog de Eric Lippert: Psychic Debugging part one y Psychic Debugging part two.

1

Como mencionaste Python, voy a señalar que los generadores en Python funcionan de manera muy similar a los generadores en C#. Solo existe la pequeña diferencia de que yield break solo puede transformar un método C# en un generador, mientras que el equivalente Python de raise StopIteration no lo hará.

>>> 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 
Cuestiones relacionadas