2011-04-18 4 views
17

Ho un metodo che restituisce un IEnumerable come questo ..Impossibile passare a un metodo per restituire IEnumerable <T>?

public virtual IEnumerable<Page> ToPages(){ 
    // foreach logic 
    yield return pages; 

    // more foreach logic 
    yield return otherPages; 

    // etc 
} 

Il metodo sembra funzionare ... in un certo senso. Ma quello che è veramente sconcertante è che non posso intervenire! Inserisco punti debugger tutto intorno, e il debugger passa proprio attraverso di loro !!!

Qualcuno sa perché questo potrebbe accadere?

+0

Mi scuso se questa sembra una domanda sciocca ... Lei didn' lo hai ignorato in una classe derivata, vero? –

risposta

27

Il metodo non viene eseguito finché non si enumera in esso.

foo.ToPages().ToList() // will enumerate and your breakpoint will be hit. 
+0

Questa è una risposta solida. IEnumerable <> implica sempre un'esecuzione pigra. Questa è una delle principali differenze tra lavorare con say a IEnumerable rispetto a un elenco . L'aroma IEnumerable restituirà semplicemente le istruzioni per l'iterazione quando arriverà il momento. Elenco in realtà cammina la raccolta e produce risultati immediatamente. –

+0

Che ha funzionato ...ma questo è appena oltre lo strano. Perché si comporta in questo modo? – Ciel

+1

Accetterò la tua risposta una volta che StackOverflow mi consentirà tra 9 minuti. Grazie. Questo mi ha davvero sconcertato. – Ciel

0

Prova a mettere una pausa sul rendimento. Questo dovrebbe risolverlo.

+0

Cosa intendi? Ho messo i punti di interruzione su ogni singola riga nell'intero metodo e non ci ha mai fatto passi avanti. – Ciel

+0

il "rendimento" è il punto in cui la funzione ritorna, dovrebbe rompere su quello. –

+0

Dovrebbe, sì. Ma non lo è. – Ciel

5

Come altri hanno notato, il corpo di un blocco iteratore viene eseguito solo quando l'iteratore è in realtà spostato. Creare l'iteratore non fa altro che crearlo. Le persone spesso trovano questo confuso.

Se il disegno e la realizzazione di blocchi iteratore interesse, qui ci sono alcuni buoni articoli sul tema:

Raymond Chen: (breve introduzione ai punti di base)

http://blogs.msdn.com/b/oldnewthing/archive/2008/08/12/8849519.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2008/08/13/8854601.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2008/08/14/8862242.aspx

Jon Skeet: (l ong, in modo approfondito)

http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

Eric Lippert (ME): (scenari avanzati e casi d'angolo)

http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/

Problemi correlati